이번에 정리할 내용은 Context다.
내가 이걸 처음 배웠을 떄 마법이라 느꼈다.
조금 과장하는면도 있지만, 여태까지의 힘들었던것들을 뚫어주는 면에서는 마법 그 자체였다.
또한, 이게 있는데 왜 힘들게 props 드릴링을 사용하지? 라는 의문도 들었다.
(이건 마지막에 서술할 context 한계에서 알아보자)
내가 왜 이런 느낌이 들었는지 정리해보겠다.
이 글에서 알아볼 것
- Context
1. Context
- 여태까지 우리는 리액트에서 데이터 전달을 props을 이용해 수행해왔다.
- 하지만 이 방식은 큰 한계점이 존재했었는데, 바로 직속으로만 전달할수있다는 점이였다. (상위 or 하위 상관없이)
- 이러면 A라는 state를 여러 곳에서 사용하고 싶거나, 직속이 아닌곳에서 사용할때 매우 많은 props 전달을 해야할것이다. (props 체인)
- 즉, 앱이 작다면 문제될것이 없지만, 앱이 커지면 커질수록 이를 관리하기가 너무 힘들어진다…
- 이를 리액트 내부에 존재하는 저장소인 Context라는 개념으로 해결할수있다
- Context 사용법
- React.createContext();
- createContext는 빈 context를 생성해준다.
- 빈 context는 단순히 빈 state의 컴포넌트이다.
- 여기에 인자로 특정 state를 넣어줄수있다..보통 객체로 넣어준다
- createContext는 빈 context를 생성해준다.
- state를 받은 React.createContext는 컴포넌트를 포함할 객체를 반환한다
- const AuthContext = React.createContext({~~~})
- 즉, AuthContext 는 컴포넌트를 포함할 객체이다.
- 이 AuthContext는 context 파일에서 필요한것이 아닌, 다른 곳에서 필요하다…따라서 내보낸다
- export default AuthContext
- const AuthContext = React.createContext({~~~})
- 앱에서 context를 사용하려면 두가지 작업이 필요하다
- 공급해줘야한다
- 리액트에게 context의 존재를 알리는것
- 보통 context의 state들은 앱 전체에 필요하므로, 최상위 루트 파일인 index.js에서 최상위 컴포넌트인 <App> 컴포넌트를 감싸주면된다
- 소비해야한다
- 연동, 리스닝등을 해줘야한다
- 이때 사용하는 것이 useContext 훅이다.
- const authCtx = useContext(AuthContext);
- authCtx.isLoggedIn(context에 정의한 state)
- 공급해줘야한다
- React.createContext();
- 위의 내용을 코드를 다시 보자
//auth-context.js
const AuthContext = React.createContext({
isLoggedIn: false,
onLogout: () => {},
onLogin: () => {},
});
export const AuthContextProvider = (props) => {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const logoutHandler = () => {
setIsLoggedIn(false);
};
const loginHandler = () => {
setIsLoggedIn(true);
};
return (
<AuthContext.Provider value={{ isLoggedIn: isLoggedIn, onLogout: logoutHandler, onLogin: loginHandler }}>
{props.children}
</AuthContext.Provider>
);
};
export default AuthContext;
//index.js
import { AuthContextProvider } from "./context/auth-context";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<AuthContextProvider>
<App></App>
</AuthContextProvider>
);
- context 제한
- 컴포넌트 구성을 대체할 수 없다
- 예를들어 재사용가능한 Button 컴포넌트에 onClick={authCtx.onLogout}을 해버리면, 이 버튼은 보통 재사용할수없다…
- 재사용할수는있지만, 무조건 버튼클릭시 로그아웃되는 버튼일것이다.
- 즉, 이런 재사용 컴포넌트에는 props를 사용하는것이 좋다
- 예를들어 재사용가능한 Button 컴포넌트에 onClick={authCtx.onLogout}을 해버리면, 이 버튼은 보통 재사용할수없다…
- 변경이 잦은 경우에는 적합하지않다
- state의 변경이 잦은 상황에 context가 최적화되어있지않다
- 이런 경우 Redux 사용하자 (다음 글에서 작성할 내용)
- 컴포넌트 구성을 대체할 수 없다
Context는 리액트를 이용해 큰 웹 애플리케이션을 구축할 때, 필수적으로 사용되어지는 기능이다.
따라서, 이를 완벽하게 이해하고있어야 한다.
단, 위에서 말한 단점 "변경이 잦은 경우에는 적합하지않다" 이 존재하는 경우에는 생각을 해봐야하는데,
이 문제를 완벽하게 해결해주는 기능이 리액트에는 또 존재한다.. 바로 Redux다.
다음 글에서는 Redux에 대해서 알아보고, Context와 Redux의 차이점도 알아보자
'OLD > React' 카테고리의 다른 글
[React] React Redux_02 (Redux Toolkit) (0) | 2023.03.05 |
---|---|
[React] React Redux_01 (Redux 기본) (0) | 2023.03.05 |
[React] React useReducer 훅 (0) | 2023.03.01 |
[React] React useEffect 훅 (0) | 2023.03.01 |
[React] React에서 사용자 입력을 컨트롤 하는 두 가지 방법 (state vs ref) (0) | 2023.02.26 |