상태관리 라이브러리 비교: Redux vs Recoil vs Zustand vs Jotai

iberis2·2023년 6월 28일
5

React 리액트

목록 보기
18/20

새 프로젝트 웹소켓을 활용한 여행 플래너 개발을 위한 상태관리 라이브러리로 어떤 걸 사용할 지, 대표적인 4가지 Redux, Recoil, Zustand, Jotai 의 각 장단점을 조사해봤다

결론

서버 데이터 상태 관리 : react query 사용
클라이언트 데이터 상태 관리 : Recoil 사용


공통 장점

  1. 컴포넌트에서 글로벌 상태의 특정 값을 의존하게 될 때 해당 값이 바뀔 때에만 리렌더링이 되도록 최적화가 되어 글로벌 상태 중 의존하지 않는 값이 바뀌게 될 때에는 컴포넌트에서 낭비 렌더링이 발생하지 않는다
  2. 타입스크립트 지원 O

🔗 Redux + 🔗 Redux Toolkit

단점

  1. 다른 상태관리 라이브러리들 중 가장 사용 방법이 복잡하다

    • 컴포넌트와 액션 사이의 연결을 설정하는 작업이 번거롭다
  2. 보일러플레이트 코드(변화없이 여러 군데에서 반복되는 코드)가 많다.

    → Redux Toolkit을 사용하면 리듀서, 액션타입, 액션 생성함수, 초기상태를 하나의 함수로 선언 할 수 있다.

  3. 비동기 요청을 위한 Redux-thunk, Redux-Saga 등의 서드파티 라이브러리가 필요하다

    • 리덕스로 요청에 관련된 상태를 관리하려면 요청 시작, 요청 성공, 요청 실패에 대한 3가지 액션들을 준비해야 하고 해당 액션들을 처리하는 로직들도 필요하다

    → react-query 로 API 요청에 대한 처리가 쉽게 가능하다.

  4. 새로 고침 시 리덕스의 store의 state가 날아간다

    redux-persist 를 설치하여 localStorag 또는 session Storage에 저장가능하다

    🔗 redux-persist 사용법

  5. Recoil, Zustand, Jotai 중 유일하게 Hook 기반이 아니다

장점

  1. 전역 상태 관리 라이브러리 중 여전히 다운로드 수 1위로 사용하는 곳이 많다

  2. Redux를 잘 다룰 줄 알면, Redux를 기반으로 만들어진 다른 라이브러리(Zustend 등)도 금방 익힐 수 있다

  3. 모든 상태 업데이트를 액션으로 정의하고, 액션 정보에 기반하여 리듀서에서 상태를 업데이트하기 때문에 상태를 더욱 쉽게 예측 가능하게 하여 유지보수 측면에 긍정적인 효과가 있다

  4. Redux Devtools를 이용해 직관적으로 전역 상태들을 볼 수 있다. 전역으로 관리해야 하는 상태값이 많아질 경우 디버깅이 편하다.

  5. 컴포넌트가 아닌 곳에서 글로벌 상태를 사용하거나 업데이트를 해야 할 때 (WebSocket을 사용 또는 리액트 네이티브 브릿지에서 연동을 할 때) getState 또는 dispatch를 바로 호출해서 사용하면 꽤 유용한 상황이 있기도 하다.

    → 아직 잘 와닿지 않는다. WebSocket 을 직접 사용해봐야 알 것 같다.

  6. 서버 사이드 렌더링이 가능하다. 서버 요청에 대한 응답과 함께 앱의 상태를 서버로 전송하여 앱의 초기 렌더링을 처리 할 수 있습니다.


API 요청 관리 : React query 로 또는 RTK Query ?

  • 둘 다 state 변경에 따라 자동으로 다시 데이터를 불러올 수 있고, 캐싱이 가능하다
  • RTK Query 보다 React query에 useInfinite query 등 기능이 더 많다
  • RTK Query에 대한 러닝 커브가 있다

🔗 Recoil

단점

  1. Redux처럼 따로 안정적인 Devtool이 없어 디버깅이 상대적으로 불편하다

  2. 어느 컴포넌트라도 전역상태에 직접 접근하여 상태를 업데이트할 수 있기 때문에 어느 컴포넌트가 언제 전역 상태를 변경하는지 알기 어렵다.

    • 기능이 점차 추가되고 전역상태가 늘어나면서 여기저기서 상태를 업데이트하게 되면 점점 상태 변경을 예측하기가 어려워진다. (유지 보수도 어려움)
  3. 새로 고침하면 Recoil State가 증발한다

    → recoil-persist 라이브러리를 사용하면 recoil state가 날라가지 않고 sessionStorage 또는 localStorage에 보관된다.

  4. 페이스북팀에서 실험단계에서 더 이상 업데이트를 안하는 것 같다(?)

장점

  1. useState 훅과 비슷하게 동작하는, 직관적이면서 간단한 구조를 가지고 있다.
    • Redux 대비 보일러플레이트 코드가 적고 사용이 간편하다
  2. Selector로 비동기 처리가 가능하다. (redux 처럼 따로 미들웨어를 설치할 필요가 없다)
    • Selector의 특징
      • Selector는 순수 함수여야 하고, Promise를 반환해야 한다
      • Selctor 는기본적으로 들어왔던 적이 있는 값을 기억하고 있기 때문에(= 캐싱), 같은 응답을 보내는 api call에 대해서는 추가적으로 요청하지 않아 성능적으로 유리하다.
      • React Suspense와 같이 사용할 수 있다. 컴포넌트에서는 selector의 비동기 데이터를 기다리는 동안 로딩 상태를 손쉽게 보여줄 수 있다.
      • React Error Boundary로 손쉽게 selector에서 던져진 에러를 잡아서 처리할 수 있다.
      • 여러 개의 비동기 쿼리를 waitForAll API를 사용해서 동시에 요청할 수 있다.

🔗Zustand

장점

  1. redux의 Redux DevTools 로 디버깅이 가능하다
  2. 보일러플레이트가 적고 redux 보다 사용이 쉽다
    • provider 필요없음 → 앱을 래핑하지 않아도 되기 때문에 불필요한 리렌더링을 최소화한다
  3. Hook 기반으로 만들 수 있다

단점

단순 사용은 정말 쉬운데 그 외 zustand에 들어있는 기능들을 사용하기 위해 공부할 수 있는 최신 한글 자료가 많이 없다.

블로그에 번역본 기사들이 올라와있긴 한데, 1 ~ 3년 전 글이고, 번역도 완벽하지 않아서 잘 걸러서 봐야한다


🔗Jotai

장점

  1. 사용이 쉽다
  2. 단순 저장소 기능 외에도 비동기 액션 처리 기능들이 내재되어 있다
    1. atom.onMount : atom 이 provider에 처음 사용되는 시점을 활용
    2. Async 간단한 비동기 액션 처리 가능
    3. Suspense와 함께 사용 가능
    4. Suspense를 사용하지 않고 fetching 상태를 직접 관리도 가능 (loading, error, data … 등)
    5. atom을 위한 Provider를 제공하는데, Provider가 없는 모드도 가능

단점

Zustand와 마찬가지로 공신력 있는 한글 자료가 많이 없다


💡 면접 대비를 위한 CS tip : 상태관리에 대한 3가지 접근 방식

Flux

  • 저장소(store) / 액션함수(action) / 리듀서 등을 통해서 상태를 업데이트 하는 방식
  • Redux, Zustand

Proxy

  • 컴포넌트에 사용되는 일부 상태를 자동으로 감지해서 업데이트 하는 방식
  • Mobx, Valtio

Atomic

  • React에 사용되는 state와 비슷하게 리액트 트리 안에서 상태를 저장하고 관리하는 방식
  • Recoil, Jotai

references

[RIDI] 리덕스 잘 쓰고 계시나요?

[요기요] Recoil을 이용한 손쉬운 상태관리

[TOAST] React 상태 관리 라이브러리 Zustand의 코드를 파헤쳐보자

[화해 블로그] Atomic state management-Jotai

profile
React, Next.js, TypeScript 로 개발 중인 프론트엔드 개발자

0개의 댓글