이번 포스팅에서는 리액트에서 전역상태를 관리할 때 많이 사용하는
Context API 와 Redux의 사용법과 장단점을 써보려고한다.
먼저, Redux는 먼저 찍먹을 해보았었다.
일단, 전역 상태 관리는 언제할까??
- 지겹도록 사용했던 useState는 지역 상태를 관리했었다.
이는 사용하는 컴포넌트 안 또는 props로 전달할때는 하위 컴포넌트에서 사용했었다. - 하지만 이렇게 props로 하나씩 계속 내려주고 하기에는 한계가 있었다.
즉, 다른컴포넌트에게 props를 사용하지않고 데이터를 넘겨주고싶었던 것이다. - 이때 사용했던 전역상태 관리도구가 Redux, ContextAPI 등이 있는 것이다.
ContextAPI 란??
- 어플리케이션에서 전반적으로 사용할 값을 관리
- 사용에서의 예는,
사용자의 언어, 로그인상태, UI(다크모드 or 라이트 모드) 등과 같이
자주 업데이트할 필요가 없는 데이터에 주로 사용한다.
ContextAPI는 Redux와 사용이유가 거의 비슷하다.
props drilling 이자식을 막기 위해서 사용하는 것이다.
Props drilling은 간단하게
이런 여러 계층의 컴포넌트들이 있다고 가정해보자.
그럼 App에서 C,G,J 컴포넌트에게 데이터를 전달하고싶으면
A,B,E,H 이렇게 굳이 props를 사용하지않는 컴포넌트들까지
다 전달을 해줘야하기 때문에 매우 비효율적이기 때문이다.
이러한 props drilling을 막기위해 ContextAPI, Redux를 사용하는 것이다.
그럼 Context를 어떻게 사용할까??
간단하게 아래의 3단계를 거쳐 사용할 수 있다.
1. createContext메서드를 사용하여 context를 만들고
MyContext변수에 상태를 저장한다.
2. 생성된 context를 가지고 context provider로 컴포넌트 트리를 감싼다.
이렇게 함으로써 Provider 컴포넌트의 하위 컴포넌트는 MyContext의 데이터("승현")에 접근이 가능
3. MyContext의 하위 컴포넌트인 Context에서 데이터를 불러와보자.
Provider라는 프로퍼티처럼 Consumer라는 프로퍼티를 사용하거나,
useContext 훅을 사용하여 컴포넌트를 더욱 간결하게 만들 수 있다.
Context가 필요 없을 경우
이걸 배우고나면 그럼 useState를 굳이 왜써..??
그냥 상태관리 다 context로 하면 안되는거야?
useState에서 관리하면 좋을 상태들을
Context로 관리하게 되면 안좋은점이 Context와 컴포넌트가 연동이 되면
컴포넌트를 재사용하기 어려워지고,
Context 내부의 값이 변경되면 Context를 사용하는
모든 자식 컴포넌트들이 리렌더링이 되기 때문에 자주 바뀌는 상태에는 context를 추천하지 않는다.
앱 전체 테마 변경
그럼 Context를 주로 사용하는 예 중에
앱 전체 테마변경을 예로 한번 살펴보자
ThemeContext.js
App.js
ThemeContext 객체 내 Provider 컴포넌트를 통한 데이터 전달
위처럼 Provider에 담은 HomeComponent 컴포넌트는
ThemeContext의 데이터(value)에 접근이 가능하다.
HomeComponent.js
Provider를 통해 데이터를 전달받은 HomeComponent 컴포넌트는
useContext를 통해 ThemeContext 객체의 데이터들을 받아올 수 있는 것이다.
즉, 콘솔로 받아온 데이터인 data를 찍어보면??
ThemeContext.Provider의 value를 잘 받은것을 볼 수 있다.
그럼, 잘 받은 데이터를 HomeComponent의 자식요소들은
props로 데이터를 내려줄 필요없이 ThemeContext에서 데이터를 가져다 쓰면된다.
헤더컴포넌트, 메인컴포넌트, 푸터컴포넌트에도 데이터를 받을 수 있다는 것이다.
HomeComponent.js
받아온 data.darkMode가 true인지 false인지에 따라
배경색과 글자색을 바꿔주어 다크모드를 구현해보았다.
HeaderComponent.js
헤더 컴포넌트에서 버튼을 만들어주어
ThemeContext에서 객체로된 데이터를 받아와, darkMode가 true인지 false인지 알 수 있게 하고,
토글버튼을 만들어서 다크모드를 껐다 켰다할 수 있게 해주었다.
리덕스를 먼저 맛을 보고
ContextAPI를 써보니까 차이점을 느꼈던 점은 크게 없었던 것 같다.
사용법과 구조의 차이...??
다른 블로그에선 단순 전역 상태 관리만 있다면 Context API,
디버깅이나 로깅 등의 상태 관리 외의 기능이나 미들웨어가 필요하다면 Redux사용을 권장한다.
각각의 단점들은
ContextAPI는 상태를 넘겨줄 때 상태가 여러개라면 Provider를 중첩해서 내려줘야 하기 때문에 불편하다.
Redux는 비동기처리를 따로 Util로 처리할 수 있는 장점이 있지만, 미들웨어를 사용하기 위해
관련개념을 이해하는 데에 많은 어려움이 있다.