React Context ?
일반적인 React에서 props 전달 흐름은 탑-다운 으로 진행된다.
전달 되는 prop이 많아지고 컴포넌트 깊이가 깊어지면 관리가 번거로워 질 수 있다.
Context Tree
는 컨텍스트 안에 포함된 모든 레벨에서 명시적으로
prop을 전달하지 않고, 어디서든 상태값에 접근 할 수 있는 방법을 제공한다.
목적
Context는 실제로 아무것도 관리하지 않는다.
단순히 값을 전달하는 파이프와 같다.
사용하는 주요 목적은 prop-drilling을 피하는 것이다.
prop-passing로직을 작성할 필요가 없기 때문에 코드가 단순해진다.
개념적으로는 종속성 주입의 한 형태이다.
자식 구성 요소에 특정한 상태값이 필요하다는것은 알고 있지만
값 자체를 생성하거나 설정하려 하지 않는다.
대신 상위 요소가 런타임에 해당 값을 전달한다고 가정한다.
Context가 '상태관리'가 아닌 이유
상태 관리는 시간이 지남에 따라 상태가 변경되는 방식을 의미한다.
아래와 같은 경우를 상태관리라 한다.
- 초기 값을 저장한다.
- 현재 값을 읽을 수 있다.
- 값을 업데이트 할 수 있다.
useState
와useReducer
가 상태 관리의 좋은 예 이다.
- hook을 호출하여 초기 값 저장
- hook을 호출하여 현재 값을 읽는다.
- 제공된 setState,dispatch함수를 호출하여 값을 업데이트 한다.
- 구성 요소가 re-render되었기 때문에 값이 업데이트 됬음을 알 수 있다.
- 마찬가지로 Redux, Mobx 도 위의 조건들을 충족하기 때문에 상태관리라 할 수 있다.
- React-Query, SWR, Apollo 및 Urql 과 같은 서버 캐싱 도구들은 가져온 데이터를 기반으로 초기 값을 설정하고 hook 들을 통해 현재 값을 반환하며 ‘서버 변화' 를 확인하여 구성요소를 다시 렌더링하기 때문에 ‘상태관리' 라고 정의 할 수 있다.
React Context의 경우 위의 조건을 충족하지 않기 때문에 상태관리 도구라고 할 수 없다.
Context는 전달되는 값을 결정하는 역할을 하고 일반적으로는 실제 상태 관리는
useSate/useReducer hook과 함께 발생한다.
정리하면 다음과 같다.
Context는 상태가 Context Tree내부에 포함된 다름 컴포넌트들과 공유되는 방식이다.
Context와 useReducer
useReducer는 Redux + React-Redux와 비슷한 구조를 가지고 있다.
- 값의 저장
- reducer 함수
- action 전달
- 값을 전달하고 컴포넌트에서 읽는 방법
그러나 기능과 동작에는 많은 차이점이 존재한다.
- Context+useReducer는 Context를 통해 현재 상태 값을 전달하는데 의존한다.
React-Redux는 context를 통해 현재 redux스토어 인스턴스를 전달한다.
- useReducer의 경우 새로운 상태 값을 생성 할 때 해당 context내부에 포함된 컴포넌트들이 상태값의 일부에만 포함되어있더라도 re-render되기 때문에 성능 문제가 발생 할 수 있다.
React-redux를 사용하면 저장소 상태의 특정 부분만 사용하고 해당 값이 변경 될 때만 re-render 할 수 있다.
- Context + useReducer 는 React 의 기능이기 때문에 React 외부에서는 사용이 불가하다. Redux 는 UI 독립적이기 때문에 React 와 별도로 사용이 가능하다.
Redux ?
애플리케이션 전체에 대한 상태 중앙 저장소 역할을 하며,
액션 이라는 이벤트를 사용하여 애플리케이션의 상태를 예측 가능한 방식으로
업데이트하기 위한 패턴 또는 라이브러리 이다.
Redux에서 제공하는 패턴과 도구들을 사용하면 상태가 언제,어디서,어떻게
업데이트 되었는지 쉽게 이해 할 수있다.
리덕스의 목적은 시간이 지남에 따라 상태 값들이 어떻게 변하는지
쉽게 이해 할 수 있도록 돕는것이다.
reducer함수를 이용하여 상태 변경을 예측 가능하게 만들고, 사이드 이펙트 및
저장소 확장 개념으로 미들웨어를 사용한다.
또한 Redux Devtools를 이용하여 앱의 작업 기록 및 상태를 확일 할 수 있다.
Redux 와 React
Redux자체는 ui에 구애받지 않는다.
React,Vue,Vanilla Js등과 함께 사용이 가능하다.
리액트에서 리덕스를 사용할때 사용되는 React-Redux 라이브러리는
redux에서 상태 값을 읽고 action을 React Component에게 전달하여
redux 저장소와 상호 작용 할 수 있도록 도와준다.
react-redux를 사용하면 애플리케이션의 모든 리액트 요소들이 리덕스 저장소에 접근이 가능하데 이는 react-redux내부에서 context를 사용하기 때문이다.
여기서 주의할 점은 react-redux는 현재의 상태값이 아닌 context를 통해
redux저장소 인스턴스만 전달한다는 점이다.
redux저장소는 react-redux요소를 사용하여 런타임에 context tree에 삽입된다.
React-Redux의 목적 및 사례
- ui레이어와 분리된 상태 관리 로직 작성이 필요할때
- 서로 다른 Ui계층간에 상태 공유가 필요할때
- redux미들웨어 기능을 빌려 액션이 전달 될 때 추가적인 로직이 필요할때
- redux상태의 유지
- Dev tool을 이용한 버그 디버깅
요약
- Context와 Redux는 같은 일을 하나
둘은 다른 도구이며, 다른 목적을 가지고 있다.
- Context는 상태관리 도구 인가?
아니다, Context API는 단지 종속성 주입의 한 형태일뿐 아무것도 관리하지 않는다.
상태관리는 일반적으로 useState,useReducer를 통해 일어난다.
- useReducer + Context API 는 Redux의 대체품인가?
그렇지 않다. 유사한 부분들이 있지만 기능에는 큰 차이가 존재한다.
주요 차이는 성능 면에서 나타나게 됩니다.
리덕스는 컴포넌트에서 글로벌 상태의 특정 값을 의존하게 될 때,
해당 값이 바뀔 때에만 리렌더링이 되도록 최적화가 되어있습니다.
반면, context는 컴포넌트에서 context의 특정 값을 의존하는경우,
해당 값이 아닌 다른 값이 변경 될 때에도 컴포넌트에서는 리렌더링이 발생하게 됩니다.
- 언제 Context,useReducer를 사용해야 하나
단순히 글로벌 상태를 사용하고자 한다면 리액트의 Context API 만으로도 충분히 구현을 할 수 있습니다.
- 언제 Redux를 사용해야 하나
- 여러 위치에 많응 야의 상태 값이 존재 할 때
- 업데이트 로직이 복잡할 때
- 거대한 코드베이스를 여러사람이 작업할 때
- 상태 변경 시각화가 필요할 때
- 사이드이펙트,메모제이션,데이터직렬화 등 관리르 위해 더 강력한 기능이 필요 할 때
참고하면 좋을 내용
https://ridicorp.com/story/how-to-use-redux-in-ridi/