본문 바로가기
REACT

useContext 훅

by 일태찡 2023. 3. 3.

 

  • 리덕스의 사용과 마찬가지로 필요한 state를 연결하기 위해 무수한 props 연결이 발생할 경우 state를 전역에 저장하여 필요한 컴포넌트에서만 꺼내 쓸 수 있는 훅입니다.
  • 일반적으로 props로 state를 연결하는 게 좋지만 특수한 한 역할만 수행하는 컴포넌트가 물리고 물려 깊이 자리 잡을 경우에는 useContext를 쓰는 것도 좋습니다.
  • 변경이 잦은 경우에는 좋지 않고 아래의 예시의 로그인 상태 같이 state가 꽤 유지될 때 사용하기 좋습니다.
  • state가 자주 변경될 땐 리덕스를 사용하는 게 좋습니다.

 

useContext를 쓰기 이전에 다른 방법을 이용한 context 설정을 먼저 해보겠습니다.

먼저 전역으로 관리할 파일을 하나 만듭니다.

 

auth-context.js

import React from 'react';

const AuthContext = React.createContext({
  isLoggedIn: false,
  onLogout: () => {}
});

export default AuthContext;

 

그리고 이 저장소를 활용할 컴포넌트에 감싸주면 됩니다.

사용할 부분에만 감싸주면 되지만 지금은 전역으로 관리한다는 가정에 전체로 감싸보겠습니다.

 

App.js

import AuthContext from './store/auth-context';
...

const App = () => {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  
  const logoutHandler = () => {
    localStorage.removeItem('isLoggedIn');
    setIsLoggedIn(false);
    
  ...

  return (
      <AuthContext.Provider
        value={{
          isLoggedIn: isLoggedIn,
          onLogout: logoutHandler
        }}
      >
        <Navigation />
        ...
      </AuthContext.Provider>
  )
};

 

지금까지 state를 설정했으니 이 state를 불러오는 방법을 알아야 합니다.

 

Navigation.js

import AuthContext from './store/auth-context';
...

const Navigation= () => {
...
  return (
      <AuthContext.Consumer>
        {(ctx) => {
          return (
            {ctx.isLoggedIn && (
              <a href="/">Users</a>
            )}
            {ctx.isLoggedIn && (
              <button onClick={ctx.onLogout}>Logout</button>
            )}
          )
        }}
      </AuthContext.Consumer>
  )
};

 

 

useContext

 

Navigation.js

import React, { useContext } from 'react';
import AuthContext from './store/auth-context';
...

const Navigation= () => {
  const ctx = useContext(AuthContext);

  return (
    {ctx.isLoggedIn && (
      <a href="/">Users</a>
    )}
    {ctx.isLoggedIn && (
      <button onClick={ctx.onLogout}>Logout</button>
    )}            
  )
};

 

이렇게 state를 호출하는 부분에 useContext 훅을 이용하면 jsx 번역문 안에 번잡하게 코드를 쓰지 않고 간결하게 끝낼 수 있습니다.

추가로 상태를 관리하는 모든 부분을 store로 옮겨  App.js를 간결하게 만들 수 도 있습니다.

 

 

auth-context.js

import React, { useState } from 'react';

const AuthContext = React.createContext({
  isLoggedIn: false,
  onLogout: () => {}
});

export const AuthContextProvider = (props) => {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  
  ...
  
  const logoutHandler = () => {
    localStorage.removeItem('isLoggedIn');
    setIsLoggedIn(false);
  };
  
  return (
    <AuthContext.Provider
      value={{
        isLoggedIn = isLoggedIn,
        onLogout: logoutHandler
      }}
    >
      {props.children}
    </AuthContext.Provider>;
  );
};

export default AuthContext;

 

index.js

...
import { AuthContextProvider } from './store/auth-context';

const root = ReactDom.createRoot(document.getElementById('root'));
root.render(
  <AuthContextProvider>
    <App />
  </AuthContextProvider>
);

 

App.js

const App = () => {
  return (
    <React.Fragment>
      <Navigation />
    </React.Fragment>
  )
};

'REACT' 카테고리의 다른 글

훅의 규칙  (7) 2023.03.06
useReducer 훅  (5) 2023.03.02
커스텀 훅으로 HTTP 요청 리팩토링  (8) 2023.02.17
커스텀 훅(Custom Hook)  (10) 2023.02.16
리액트 최적화 테크닉  (7) 2023.02.14