October 07, 2021
context api 에서 상태값을 변경하면, provider 로 감싼 모든 자식 컴포넌트들이 리렌더링한다. 그래서 context api 를 상태관리 도구로 사용하면 각 자식 컴포넌트들이 리렌더링하지 않도록 방어할 필요가 있다. 결론적으로 context api 는 상태관리 도구로 사용하면 props drilling 을 회피한다는 장점보다 잃는 것이 더 많다.
redux 는 보일러플레이트 코드가 많다. recoil 은 아직 개발 단계이다. mobx 는 써본 적이 없어서 이야기하지 않겠다.
위의 전역 상태 관리 도구를 사용하지 않으면, props drilling 으로 각 컴포넌트들의 상태를 관리해야 한다.
그런데 간혹 상태값이 필요한 컴포넌트와 부모 컴포넌트 사이에 낀 중간 컴포넌트가 존재할 때가 있다. 그 중간 컴포넌트는 부모와 자식의 상태를 매개하기 위해서만 props 를 받는다. 이런 중간 컴포넌트가 많아지면 redux 의 보일러플레이트 만큼 코드량이 많아진다.
context api 를 쓰면 그런 중간 컴포넌트를 건너뛰고 바로 대상으로 하는 컴포넌트로 전달할 수 있다.
props 가 필요한 컴포넌트 입장에서는 context api 가 전달해주는 props 든 전역 상태 관리가 전달하는 props 이든 구분할 이유가 없다. 그래서 사용하는 개발자도 props 를 전달하는 목적을 달성할 수 있다는 이유만으로 구분하지 않는다. 그래서 context api 를 상태 관리 도구처럼 착각한다.
react-redux
는 Provider
를 제공한다. 이걸 context api 라고 생각할 수 있다. props 로 store 를 받는 것조차 동일하다.
이에 대해서 다음 글 두개를 참고하자.
결론적으로 react-redux
도 context api 를 사용했다가 다시 각 컴포넌트가 store 를 직접 구독하는 방식으로 변경한 것을 알 수 있다.
context api 는 props drilling 대신 사용하는데 유용하다. 즉 provider 내부에서 상태 변경이 거의 일어나지 않는다면, 해당 상태를 provider 하위의 다른 컴포넌트에 전달하는 용도로 쓰는데 적합하다.
그 예시로 주로 locale 이나 theme 정보 등을 언급한다.
햐지만 거의 상태변경이 일어나지 않으면서 전역적으로 사용이 필요한 개체를 초기화하는 위치로도 적합하다.
이렇게 context api 를 사용해서 개체를 초기화 하는 경우, 몇가지 장점이 있다.
테스트 코드를 작성할 때 provider 를 감싸주는 것으로 mocking 을 대신할 수 있다. 물론 이 경우 초기화하는 개체에 테스트가 의존성을 가지기 때문에 유닛 테스트 대신 통합 테스트에 어울린다.
context 의 provider 가 인터페이스 역할을 하면서 컴포넌트 간의 결합성이 낮아지고, provider 를 교체하는 것만으로 훗날 명세 변경에 대응할 수 있다.