예전에 상태 관리 라이브러리에 대해 정리한 적이 있지만, 라이브러리를 실제로 사용해보면서 느낀 점과 리액트 딥다이브 책을 읽으면 알게 된 점, 여러 글들을 찾아 읽어보면서 알게된 점을 바탕으로 종합 정리하는 글이다.
처음 MV_ 패턴과 Flux 패턴에 대해 설명을 들으면서 명확하게 이해되지 않았던 것들이 프론트엔드에서 MV* 아키텍쳐란 무엇인가요?을 보고 이해하는데 큰 도움이 되었다. 한 번쯤 읽어보는 것을 적극 추천한다.
본인이 가장 크게 깨달은 건 MVC, Flux 패턴이 말 그대로 "패턴"이라는 점이다. 리액트로 MVC 패턴을 구현할 수도 있고, Flux 패턴을 구현할 수도 있는 인터페이스다. 무엇을 M, V, C로 정의하느냐에 따라 달라진다. 지금까지 이 맹점을 놓쳐 스스로 혼란을 일으키고 있었던 것 같다.
상태 관리 라이브러리에 대해 공부하면서 기술을 공부할 때와 기술을 도입할 때는 어떤 것을 고려해야 하는지에 대한 시각을 갖게 되었다. (드디어 결론...) 그래서 본 글에서는 이와 관련된 내용을 정리하고, 해당 내용을 기반으로 여러 상태 관리 라이브러리에 대해 정리해보고자 한다.
기술을 공부할때는!
- 이 기술이 나온 배경이 무엇인지
- 해결하고자 하는 문제가 무엇인지
- 어떻게 해결했는지
상태 관리 라이브러리를 공부할때는!
- 핵심 개념, 원리가 무엇인가
- 비동기, 미들웨어를 지원하는가
- 리액트 지원 버전 또는 원하는 기술스택(next.js, typescript 등)을 지원하는가
- 개발자 도구를 지원하는가(디버깅이 용이한가)
상태 관리 라이브러리를 도입할때는!
- 전역으로 관리해야 하는 상태는 어떤 것인지(어떤 문제를 해결하고자 하는건지)
📌 상태(State)
: 어떠한 의미를 지닌 값, 시나리오에 따라 지속적으로 변경될 수 있는 값
종류
- Local State: 리액트 컴포넌트 안에서만 사용되는 state
- Global State: Global Store에 정의되어 프로젝트 어디에서나 접근할 수 있는 state
- Server State: 서버로부터 받아오는 state
분류
- UI
- 애플리케이션의 대화 형 부분을 제어하는데 사용되는 상태입니다
- 예 : 다크 모드 토글, 모달
- URL
- 브라우저에서 관리하는 상태
- 예: 제품 필터링, 쿼리 매개 변수에 저장, 필터링 된 동일한 제품을보기 위해 페이지 새로 고침
- form
- 양식의 다양한 상태
- 예: 로드, 제출, 비활성화, 유효성 검사, 재시도
- 제어/비제어
- 서버에서 가져온 값
- 빠른 액세스를 위해 클라이언트 측에 캐시하는 서버의 상태입니다
- 예: API 호출, 결과 저장, 여러 위치에서 사용
- State Machine
- 시간 경과에 따른 상태의 명시적인 모델
- 예 : 신호등이 녹색 → 노란색 → 빨간색으로 표시되지만 녹색 → 빨간색은 아님
📌 타임라인
- 초창기 웹 서비스의 MVC 아키텍쳐
- jQuery시절의 MVC 아키텍쳐
- MVVM 아키텍쳐 - angular, react, vue
- 컴포넌트 그리고 Container-Presenter 패턴
- Props Drilling Problem
- 2014 – Flux 패턴 (많은 라이브러리들)
- 2015 – Redux
- FLUX 패턴의 한계
- Observer-Observable Pattern
- 2016 – MobX
- 2018 – Context
- 2019 – Hooks 도입 (+ React Query, SWR)
- 2019 – Zustand
- 2019 – xState
- Atomic 패턴
- 2020 – Jotai, Recoil, Valtio
- 2021 – useSelectedContext
- flux 패턴을 redux로 만듬, 관측형에 대한 니즈로 mobx탄생, 한 동안 서버캐싱과 UI 상태를 두 가지 중 하나로 관리
- context로 props-drlling을 해결하기 위해 나옴
- hooks의 탄생 이후로 서버캐싱 라이브러리인 react-query, swr이 나옴
- 전역 상태 캐싱을 편하게 하기 위한 여러 라이브러리들 탄생(jotai, recoil, valtio)
- context를 좀 더 캐싱하기 쉽게 useSelectedContext 탄생함
📌 패턴별 상태 관리 라이브러리
1. Flux 패턴
💡 MVC → FLUX 개선 방향
- 공통적으로 사용되는 비지니스 로직의 Layer와 View의 Layer를 완전히 분리되어 상태관리라는 방식으로 관리한다.
- 각각의 독립된 컴포넌트가 아니라 하나의 거대한 View 영역으로 간주한다.
- 둘 사이의 관계는 Action과 Reduce라는 인터페이스로 분리한며 Controller는 이제 양방향이 아니라 단반향으로 Cycle을 이루도록 설계한다.
Top-down
2. Observer-Observable 패턴
💡 Flux 복잡해! → Observer
- FLUX와 동일하게 거대한 View와 상태관리인 Model을 나누는 관점을 동일
- 복잡함을 야기하는 Dispatch와 Action을 배제하고 값이 바뀌면 바뀐 값을 모두에게 전달을 한다는 개념
Proxy 패턴
3. Context API, useContext Hook
💡 Flux → Context 개선 방향
- View와 Model은 분리한다.
- 프레임워크에서 Props Drilling Problem를 막는 방법을 제공하자!
(Tanstack Query, SWR)
💡 Flux, Atomic 복잡해! → MVC의 개념 확대
- 서버와의 fetch 영역을 Model로 간주
- View는 React
- Controller는 query와 mutation이라는 2가지의 인터페이스를 통해서 서버 데이터의 상태를 관리하고 캐싱, 동기화, refetch등을 관리해주는 역할
React에서 서버 데이터를 최신으로 관리하기(React Query, SWR) | 카카오엔터테인먼트 FE 기술블로그
4. Atomic 패턴
💡 Flux 복잡해! → Atomic
- View와 Model은 분리한다.
- 중간의 과정은 자율에 맡기고 간단하게 Model에 접근하는 법만 제공하자.
- 동기화, 동시성 처리가 중요
Bottom-up
📌 Global State
Redux
- 2015
- 핵심 개념 : store, action, reducer, dispatch, selector
- 미들웨어 O
- 비동기 처리: redux-thunk, redux-saga
- 데이터 fetching 라이브러리는 리덕스 RTK 추천
- 리액트 18, next.js?
- 개발자 도구 O
Zustand
- 2019
- 공식 문서
- 핵심 개념 : create, useStore, Action, state, set/setState/dispatch, selector
- 비동기/동기 미들웨어 O
- persist, immer, devtools, subscribeWithSelector 등
- 데이터 fetching 라이브러리는 SWR, React Query 추천
- 리액트 18, next.js O
- 개발자 도구 O
mobX
- 2016?
- 공식 문서
- 핵심 개념 : observable state, action, computed, derivation
- 비동기/동기 O
- 데이터 fetching 가능
- 리액트 18 O
- 개발자 도구 O
우아한 기술 블로그 | React에서 Mobx 경험기 (Redux와 비교기)
Valtio
- 2021
- 공식 문서
- 핵심 개념 : proxy, useSnapshot, actions
- 비동기/동기 flow 제공
- 데이터 fetching 기능 별로 없음, 가능하지만 RQ 또는 SWR
- 리액트 18 O, next.js?
- 개발자 도구 O
Recoil
- 2020
- 핵심 개념 : atom, useRecoilState, selectors, recoilRoot
- 비동기/동기 미들웨어 없지만 추가작업은 가능
- 데이터 fetching 가능하지만 SWR, React Query 사용
- 리액트 18 X, next.js?
- 개발자 도구 X
Jotai
- 2021
- 핵심 개념 : atom, useAtom, store, provider
- 비동기/동기 미들웨어 없지만 추가작업은 가능
- 데이터 fetching 가능 또는 SWR, React Query 사용
- 리액트 18, next.js
- 개발자 도구?
--
📌 Server State
Tanstack-Query
SWR
마무리