Context API보다 Redux의 어떤 장점 때문에 많이 사용하는 걸까 라는 생각이 들어서 "Context API의 한계"에 대해서 찾아보던 중
React Context is Not optimized for high frequency updates.
이유가 무엇일까 생각해보니, React 공식문서에서 Context는
Provider 하위에서 context를 구독하는 모든 컴포넌트는 Provider의 value prop가 바뀔 때마다 다시 렌더링 됩니다.
// store/rundata-context.js
export const RunDataContext = React.createContext({
runData: [],
appendRunIten: () => {},
});
export const RunDataContextProvider = ({ ...props }) => {
const [runData, setRunData] = useState();
const appendRunItem = (newRunData) => {
setRunData([newRunData, ...runData]);
};
return (
<RunDataContext.Provider
value={{ appendRunItem, runData }}
>
{props.children}
</RunDataContext.Provider>
);
// component/RunHome.js
import { RunDataContextProvider } from 'store/rundata-context';
export const RunHome = () => {
initLocalData();
return (
// RunDataContextProvider의 value prop이 바뀔때마다
// AddRunItem, RunItemList는 re-rendering 된다.
<RunDataContextProvider>
<AddRunItem />
<RunItemList />
</RunDataContextProvider>
);
};
예시와 함께 보자면, RunDataContextProvider value prop이 바뀌면 해당되는 Context에 속하는(Context Provider Component 자식인) AddRunItem, RunItemList Component도 re-rendering 됩니다.
이러한 이유로 빈번한 상태 변화가 있을 경우에는 설계에 따라 크게 자원이 소모될 수 있기 때문에 "빈번한 변화에 최적화되어 있지 않다." 라고 쓰여있던 것이라고 생각합니다.
- React Context is Not optimized for high frequency updates.
프로젝트에 Context API만을 적용하면 eslint에서 다음과 관련된 에러가 발생합니다.
위 링크에서도
이것은 컨텍스트 공급자와 소비자가 하위 트리의 모든 요소를 다시 렌더링하게 할 뿐만 아니라 공급자를 렌더링하고 소비자를 찾기 위해 트리 스캔 반응에 대한 처리도 낭비되기 때문에 성능이 상당히 저하될 수 있습니다.
여기서 다시 드는 생각이 그러면 React.Memo로 부모 컴포넌트의 변화에 대응하고, 위 eslint에서 언급한 것처럼 useMemo, useCallback을 사용하면 되는거 아닌가? 하는 의문이 들 때쯤에 이 질문을 던졌던 톡방에 선생님이 답변을 주셨는데 감사합니다..
복잡한 전역 상태 관리를 해야 할 때 ContextAPI는 Context가 공급하는 value가 변경되면 해당 Context에 속하는(ContextProvider 컴포넌트의 자식인) 컴포넌트들이 모두 리렌더 됩니다.
반면 Redux는 스토어의 특정 값이 변화하였을 때 해당 값을 구독하고 있는 컴포넌트만 리렌더가 발생합니다.
물론 Context를 사용할 때에도 Context 분리, useCallback, useMemo, React.memo으로도 Redux와 동일한 급의 최적화가 가능하지만 그 정도로 최적화가 필요하고 복잡한 상태관리가 필요하다면 Redux가 현명한 대안이 될 수 있습니다.
현재 프로젝트처럼 규모가 작은 프로젝트에서는 Context API와 메모이제이션을 통한 최적화, 규모가 큰(복잡한 상태관리 및 구조) 경우에는 Redux 적용
하지만 Redux 공부를 해야하기 때문에 다음 토이프로젝트에 Redux 적용해보는 걸로..