서론
React의 경우 props로 상위컴포넌트에서 하위컴포넌트로 값을 전달하는데, 이때 구조상 하나의 데이터를 여러 곳의 컴포넌트에 공통으로 사용해야 된다면 상태 관리 라이브러리를 사용한다. 대표적으로 Redux, Mobx, context API , Recoil 총 4개의 라이브러리가 있는데, 각 프로젝트에 상황과 선호도에 따라서 사용할 수 있는 라이브러리가 다르다. 그러므로 각각의 라이브러리들의 장단점을 정리해서 알맞게 사용해보려고 한다.
Redux
React에서 가장 많이 사용하고 있는 Javascript 상태 관리 라이브러리이다.
Redux 언제 쓰면 좋냐?
- 앱의 여러 위치에서 필요한 많은 양의 상태들이 존재 할때 ( 전역 상태가 필요하다고 느껴질 때 )
- 상태들이 자주 업데이트 될 때
- 상태를 업데이트 하는 로직이 복잡할 때
- 앱이 중간 또는 큰 사이즈의 코드를 갖고 있고 많은 사람들에 의해 코드가 관리될 때
- 상태가 업데이트 되는 시점을 관찰할 필요가 있을 때
1. 장점
- 쉬운 디버깅
action을 dispach 할 때마다 기록이 남아서 에러를 찾기가 용이하다. 타임머신 기능을 통해서 버그나 이전 상태로 돌아가서 테스트가 가능하다. - 상태의 중앙화
store라는 이름의 전역변수를 사용하여서 상태를 한 곳에서 관리하는 상태의 중앙화가 가능하다. - 실행 취소 기능 구현 가능
상태를 읽기 전용으로 취급하여 이전 상태로 돌아가기 위해서는 그저 이전 상태를 현재 상태에 덮어쓰기만 하면 된다. 실행 취소 기능 구현이 가능하다.
2. 단점
- 코드량 증가
작업하는 코드량이 증가할 수 있다. 작은 기능을 사용하더라도 필수적으로 생성해야 되는 소스 ( 예로 action ) 때문에 코드량이 증가한다. - 실수로 상태를 직접 변경이 가능
Redux는 상태를 읽기 전용으로 취급할 뿐, 실제 읽기 전용으로 만들어주지 않는다. 그래서 상태를 실수로 직접 변경하지 않도록 항상 주의해야 된다. but immutable.js 같은 라이브러리 사용하면 예방은 가능하다. - 높은 러닝커브
러닝 커브가 높다. 확실히 React 개념뿐만 아니라 Redux 불변성 개념까지 잘 이해하고 있어야 한다.
Mobx
MobX는 functional reactive programming을 투명하게 적용함으로써 상태 관리를 쉽고 확장성 있게 만들어주는 검증된 라이브러리입니다
Mobx는 렌더링 할 State를 관찰대상으로 지정, State를 변경하면 React Component Render 메서드에 의해서 Rerendering 되는 아키텍처를 기본 골격으로 합니다. 예제와 함께 Mobx의 작동 방식과 특징을 알아 보겠습니다.마치 Java Spring Framework유사한 Layer 아키텍쳐를 가지고 있고 실제로 그런 식으로 Layer를 분리하여 아키텍처를 구성하는 것을 권장하고 있습니다.
Moxb과 잘 맞는 프로젝트
- 한 스토어에 저장되는 데이터가 명확하고, 드물게 다른 스토어에 있는 데이터에 접근하는 경우
- 작은 프로젝트
- 복잡한 상태관리가 요구되지 않는 경우
1. 장점
- 사용이 간단
Redux 보다 사용이 간단하다. - 객체지향적이라서 낮은 러닝커브
객체지향적이다. class사용을 권장한다. 그래서 서버 개발자들에게 보다 친숙하고 낮은 러닝커브를 제공한다. - 캡슐화
state의 변경을 오직 메서드를 통해서만 변경이 가능하게 설정이 가능하다.
2. 단점
- 상태 추적이 굉장히 불편
Redux와는 다르게 별도의 디버깅 툴이 없어서 상태 추적이 굉장히 불편하다. 일일이 console.log로 확인을 해야 된다. - 적은 레퍼런스
레퍼런스 가능한 코드가 부족한다. 특히 함수형은 찾아보기가 힘들다. - MobX에서 실시간 상태 변화를 하거나 다른 스토어에 있는 데이터에 접근을 해야 되는 경우라면 Mobx의 multiple domain store 보다 Redux의 단점이라고도 하는, single domain store가 더 잘 맞을지도 모른다.
Context API
React에서 자체 제공하는 API이다. context api에서 상태값을 변경하면, provider로 감싼 모든 자식 컴포넌트들이 리렌더링 한다.
context api는 props drilling 대신 사용하는데 유용하다. 즉 provider 내부에서 상태 변경이 거의 일어나지 않는다면, 해당 상태를 provider 하위의 다른 컴포넌트에 전달하는 용도로 쓰는데 적합하다.
그 예시로 주로 locale이나 theme 정보 등을 언급한다.
하지만 거의 상태변경이 일어나지 않으면서 전역적으로 사용이 필요한 개체를 초기화하는 위치로도 적합하다.
이렇게 context api를 사용해서 개체를 초기화하는 경우, 몇 가지 장점이 있다.
- 테스트 코드를 작성할 때 provider를 감싸주는 것으로 mocking을 대신할 수 있다. 물론 이 경우 초기화하는 개체에 테스트가 의존성을 가지기 때문에 유닛 테스트 대신 통합 테스트에 어울린다.
- context의 provider 가 인터페이스 역할을 하면서 컴포넌트 간의 결합성이 낮아지고, provider를 교체하는 것만으로 훗날 명세 변경에 대응할 수 있다
- Root 파일에서 구성한 Provider을 내려줍니다.
- 사용하고자 하는 컴포넌트에서 작성해놓은 Dispatch와 State를 꺼내서 사용합니다.
- Reducer를 여러 개 만들면 Provider에서 여러 단계로 만들어서 사용할 수 있습니다
1. 장점
- 설치가 필요 없음
React에서 제공하는 기술이라서 별도의 설치가 필요 없다. - 낮은 러닝커브
Mobx와 Redux에 비해서 낮은 러닝커브를 가진다. - 코드가 간결하다.
2. 단점
- 렌더링
context api에서 상태값을 변경하면, provider로 감싼 모든 자식 컴포넌트들이 리렌더링 한다. 그래서 context api를 상태관리 도구로 사용하면 각 자식 컴포넌트들이 리렌더링 하지 않도록 방어할 필요가 있다. 결론적으로 context api는 상태관리 도구로 사용하면 props drilling을 회피한다는 장점보다 잃는 것이 더 많다.
Recoil
facebook에서 만든 상태관리 라이브러리이다. 기존 context의 렌더링 문제, 단일값만 저장 가능한 문제(consumer를 가지는 여러 값의 집합을 저장 못하는 문제), 코드 분할의 어려움을 해결하고자 만든 라이브러리이다.
1. 장점
- 내부 접근성 쉽다.
React 전용 라이브러리라서 그런가 React 내부 접근성이 용이하다. - 코드 분할이 가능해진다.
- 컴포넌트 비수정
컴포넌트를 수정하지 않고 상태 데이터로 대체 가능하며 파생된 데이터를 사용 시 동기식과 비동기식 간에 이동이 가능하다.
2. 단점
- 호환 문제가 있다.
Recoil 빌드는 ES5로 트랜스파일 되지 않으므로, Recoil을 ES5와 사용하는 것은 지원하지 않는다. -Recoil- - 레퍼런스가 부족하다.
맺음말
일단 시작은 React 강의에서 선생님께서 사용하신 context API를 보면서 다른 상태 관리 라이브러리들의 장단점을 비교해보고 싶었다. 아무래도 아직은 시작하는 단계라서 어느 때 어떤 라이브러리가 딱 맞는지 모르지만, 서칭을 해보면서 다른 분들의 간접경험들을 통해서 어느 때 써보아야겠다는 감 정도 생겼다. 완벽한 라이브러리는 없다. 하지만 상황에 따라서 적절하게 사용한다면 될 것 같다. Redux가 러닝커브가 높은 만큼 좀 시간을 가지고 공부해보고 비교적 러닝 커브가 낮은 context API와 Recoil 먼저 공부해봐야겠다.