- 리덕스의 사용과 마찬가지로 필요한 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 |