본문 바로가기

프론트엔드/ReactJS

Redux vs. React Context (2) - 왜 Context는 "상태 관리"가 아닌가

이 글은 다음 페이지 일부를 번역했습니다.

https://blog.isquaredsoftware.com/2021/01/context-redux-differences/#why-context-is-not-state-management

 

Blogged Answers: Why React Context is Not a "State Management" Tool (and Why It Doesn't Replace Redux)

Definitive answers and clarification on the purpose and use cases for Context and Redux

blog.isquaredsoftware.com

 

왜 Context는 "상태 관리"가 아닌가

 

"상태"는 애플리케이션의 동작을 설명하는 모든 데이터입니다. 원하는 경우 "서버 상태", "통신 상태" 및 "위치 상태"와 같은 범주로 나눌 수 있지만 핵심은 저장, 읽기, 업데이트 및 사용되는 데이터가 있다는 것입니다.

 

XState 라이브러리의 저자이자 상태 머신 전문가인 David Khourshid는 다음과 같이 말했습니다:

"상태 관리는 상태가 시간이 지남에 따라 어떻게 변하는지 입니다."

 

이를 바탕으로 "상태 관리"는 다음을 수행하는 방법을 의미한다고 말할 수 있습니다.

  • 초기 값을 저장하고
  • 현재 값을 읽고
  • 값을 업데이트하는 것

또한 일반적으로 현재 값이 변경되었을 때 알림을 받는 방법이 있습니다.

 

React의 useStateuseReducer hook은 상태 관리의 좋은 예입니다. 두 hooks를 사용하여 다음을 수행할 수 있습니다.

  • hook을 호출하여 초기 값을 저장할 수 있다.
  • hook을 호출하여 현재 값을 읽을 수 있다.
  • 제공되는 setStatedispatch를 호출하여 값을 업데이트 할 수 있다.
  • 컴포넌트가 리렌더링되므로 값이 업데이트 되었음을 알 수 있다.

마찬가지로 Redux와 MobX도 분명히 상태 관리입니다.

  • 우리는 Redux의 루트 리듀서를 호출하여 초기 값을 저장하고, store.getState()로 현재 값을 읽고, store.dispatch(action)로 값을 업데이트하고, store.subscribe(listener)를 통해 저장소가 업데이트되었음 리스너에게 알릴 수 있다.
  • MobX는 store 클래스에 필드 값을 할당하여 초기 값을 저장하고, store의 필드에 액세스하여 현재 값을 읽고, 해당 필드에 할당하여 값을 업데이트하고, autorun()computed()를 통해 변경 사항이 발생했음을 알립니다.

React-Query, SWR, Apollo 및 Urql과 같은 서버 캐싱 도구가 "상태 관리"의 정의에 부합한다고 말할 수도 있습니다 - 가져온 데이터를 기반으로 초기 값을 저장하고, 그들의 hook을 통해 현재 값을 반환하고, "server mutations"를 통해 업데이트를 허용하고, 구성 요소를 리렌더링하여 변경 사항을 알립니다.

 

React Context는 이러한 기준을 충족하지 않습니다. 따라서 컨텍스트는 "상태 관리" 도구가 아닙니다!

 

이전에 설정했듯이, Context는 자체적으로 어떤 것도 "저장"하지 않습니다. <MyContext.Provider>를 렌더링하는 부모 컴포넌트는 컨텍스트에 전달할 값을 결정하는 역할을 하며 해당 값은 일반적으로 React 컴포넌트의 상태를 기반으로 합니다. 실제 "상태 관리"는 useState/useReducer 후크에서 발생합니다.

 

David Khourshid는 또한 다음과 같이 말했습니다:

컨텍스트는 (이미 어딘가에 존재하는)상태가 다른 컴포넌트와 공유되는 방식입니다.

컨텍스트는 상태 관리와 거의 관련이 없습니다.

 

또한, 최근 트윗에서 다음과 같이 말합니다:

컨텍스트는 추상화된 상태보다 숨겨진 prop과 비슷하다고 생각합니다.

 

이런 식으로 생각해봅시다. 우리는 똑같은 useState/useReducer 코드를 작성할 수도 있었지만 컴포넌트 트리를 통해 데이터와 업데이트 함수를 prop-drilling했습니다. 앱의 실제 동작은 전반적으로 동일했을 것입니다. Context가 하는 일은 prop-drilling을 건너뛰도록 하는 것뿐입니다.