Context API로 값, 상태 전역관리하기
👉 Context API
- 프로젝트 안에서 여러 컴포넌트들에 값을 전해줘야 할 때 전역적으로 사용 할 수 있는 있도록 하는 것. ( 전역으로 사용되는 상태,값 관리 )
- 적은 컴포넌트들로 이루어진 프로젝트에서는 큰 필요가 없지만 많은 컴포넌트들로 구성된 프로젝트에서 편리함.
: 값을 관리 할 수 트리 단계마다 명시적으로 props를 넘겨주지 않아도 많은 컴포넌트가 이러한 값을 공유하도록 할 수 있다.
: 이 값은 꼭 상태를 가르키지 않아도 된다. 함수, 외부 라이브러리 인스턴스, DOM 등 모두 가능.
cf) props : 부모 컴포넌트에서 자식 컴포넌트로 값을 넘겨주는 역할.
1. Context API를 사용하여 새로운 context만들기
-
React.createContext(parameter)
- 파라미터에는 Context 의 기본값을 설정한다.
- 리액트 16.3부터 도입
- redux의 store와 같은 역할로, createContext()를 이용하여 특정 파일을 만들어 데이터를 넣어둔다.
: Context 를 쓸 때 값을 따로 지정하지 않을 경우 사용되는 기본 값이므로, 이 컴포넌트를 사용할 때, value
로 값을 설정할 것.
: Context 안에 Provider 라는 컴포넌트가 있는데 이 컴포넌트를 통하여 Context 의 값을 정하고 내보낼 수 있음.
2. 생성한 ContextAPI파일을 부모 컴포넌트에 적용시키기
- Context를 사용하여 전역 데이터를 사용하려면 공통 부모 컴포넌트에 Context의 Provider로 감싸서 하위 트리에 값을 보내야한다.
- 위의
UserInfoContext.tsx
를 불러오고 App.js
에 감싸줬으니 하위 컴포넌트들은 UserInfoContext.tsx
안에있는 state
에 자유롭게 접근할 수 있다.
3. App.js에서 전역으로 적용시킨 ContextAPI를 하위 컴포넌트에서 사용하기.
React-Hook
중 하나인 useContext
불러오기
4. context api의 문제.
const ModalToggleButton = () => {
const [, setShow] = useContext(ModalContext);
return <button onClick={() => setShow((state) => !state)}>모달토글</button>;
};
const Modal = () => {
const [show] = useContext(ModalContext);
return show ? <div>모달</div> : null;
};
const App = () => {
return (
<ModalProvider> //----- <ModalProvider/> = contextAPI
<ModalToggleButton />
<Modal />
</ModalProvider>
);
};
🔩 Provider hell
- 위 코드와 같은 구조일 때, 버튼을 클릭하면
<Modal />
만 렌더링 되는 것이 아니라 <ModalToggleButton />
도 같이 렌더링이 되는 것이다.
= why? ) Context.Provider
는 value
로 저장된 값이 변경되면 useContext(Context)
를 사용하는 컴포넌트도 같이 렌더링을 한다. 그렇기 때문에 show
라는 상태를 사용하지 않는 <ModalToggleButton />
도 같이 렌더링이 된다.
= !!! 해결방법 !!! = contextAPI를 상태값
, 액션
을 나누어따로 만들고 감싸준다.
but .... 간단한 boolean
값 정도는 괜찮을지 모르지만 여러 state
라면 object
에서 상태가 부분적으로 변경이 되더라도 컨텍스트를 사용하는 모든 컴포넌트가 리렌더링 될 것이다. 그리고 컨텍스트를 추가할 때마다 프로바이더로 매번 감싸줘야하기 때문에 Provider hell
을 야기할 수 있다.
- 이런 이유들로
contextAPI
가 있음에도 Redux
,Recoil
등의 전역 상태관리 라이브러리를 사용하는 것.
- 전역 상태관리 라이브러리
ContextAPI
참고1
참고2