애드블럭 종료 후 보실 수 있습니다.

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React 최신 상태관리 라이브러리 비교하기 (feat. zustand, redux-toolkit, jotai, recoil)
    React 2022. 8. 16. 17:28
    728x90
    반응형

    1. redux-toolkit(rtk)을 그만 사용하려는 이유

    나의 경우 react를 시작하고 redux-saga -> mobx -> redux-saga -> redux-toolkit 순으로 사용했을 정도로 redux의 사용을 좋아하고 즐겨 사용했다.

    하지만 이제 api 통신을 react-query로 변경하고 프로젝트를 진행하는 요즘에는 rtk를 통한 글로벌 상태 관리를 하는 경우가 무척 줄어들거나 아예 사용하지 않는 프로젝트들이 생겨났다.

    상황이 이렇게 되니 rtk의 단점들이 보이기 시작했고 두 가지 글로벌 상태 관리 라이브러리를 선택했다.

    2. zustand와 jotai

    두 라이브러리는 각각 독일어와 일본어로 상태를 뜻하는 단어로 이름에서 알 수 있듯이 모두 Poimandres의 카토 다이시가 주가 되어 제작한 라이브러리들이다.

     

    두 라이브러리들은 zustand -> redux, jotai -> recoil에서 영감을 받아 제작했다.

    그럼 이제 각각 영감을 받은 라이브러리들과 상대적 강점이 있는지 알아보자.

    2.1 zustand vs RTK

    rtk의 11.8mb라는 큰 사이즈와 달리 zustand는 187kb라는 압도적으로 작은 크기를 가지고 있다.

    작은 크기에 걸맞게 toolkit과 달리 무척 간단하게 설정하여 사용할 수 있다. (ex. rtk provider vs zustand not provider)

    그리고 zustand의 subscribe기능을 사용하면 자주 렌더링 되는 항목에 대해서 랜더링을 유발하지 않고 변경하는 처리하는 어찌 보면 소소하지만 강력한 기능도 존재한다.

    이 정도만으로도 thunkAPI 등의 rtk기능들을 사용하지 않는다면 충분히 zustand로 갈아탈만한 조건이 된다고 생각한다.

    비교 zustand redux-toolkit(rtk) 결과
    번들사이즈 187kb 11.8mb zustand
    Provider 여부 X O zustand
    설정 복잡도 간단 상대적으로 복잡 zustand
    Transient updates O X zustand
    다운로드 수 646k 1798k rtk
    깃허브 Star 20.6k 8.3k zustand

     

    2.2 jotai vs recoil

    jotai(830kb) 역시 recoil(2.17mb) 대비하여 압도적인 크기 차이가 존재한다.

    거기에 rtk, zustand, jotai 모두 TS로 작성된 것에 비해 recoil은 JS로 작성되어 있다는 단점이 존재한다.

    그리고 소소하지만 atom에 key값을 넣어줄 필요가 없어 코드의 길이가 줄어드는 효과도 존재한다.

    jotai와 recoil의 비교는 zustand와 rtk보다 더 간단한데, 활발하게 업데이트가 진행되고 있는 jotai에 비해 recoil은 아직 1 버전도 되지 않은 상황이다.

    이건 여담이지만 Kent.C.Dodds가 recoil보다 jotai를 더 선호한다고도 이야기했다.

    비교 jotai recoil 결과
    번들 사이즈 830kb 2.17mb jotai
    Key 사용 여부 X O jotai
    TS O X jotai
    다운로드 수 130k 303k recoil
    깃허브 Star 9.6k 17.4k recoil

    3. zustand vs jotai

    위에서 비교한 결과에 따라 나는 zustand와 jotai를 사용할 계획을 세웠다.

    두 라이브러리 모두 훌륭한 라이브러리들이고 여기부터는 취향에 가까운 영역이라고 생각한다.

    jotai의 문서에서는 아래와 같은 경우로 사용법을 나누고 있다.

    • useState + useContext 대체하는 경우 - jotai
    • react 이외에서도 사용해야 되는 경우 - zustand
    • code splitting이 중요한 경우 - jotai
    • redux devtools를 선호하는 경우 - zustand
    • react suspense를 활용하고 싶은 경우 -jotai

    이외에도 bottom-top(jotai)와 top-bottom(zustand)로 이루어져 있으면 jotai의 경우 react-query 등의 다른 라이브러리들과 쉽게 연동할 수 있다는 장점이 존재한다.

    비교 zustand jotai 결과
    번들 사이즈 187kb 830kb zustand
    devtools O X zustand
    연동성 X O jotai
    설정 복잡도 간단 간단 비슷함
    suspense 지원 X O jotai
    다운로드 수 646k 130k zustand
    깃허브 Star 20.6k 9.6k zustand

    4. zustand와 jotai 예시

    4.1 zustand

    // store.ts
    import create from 'zustand';
    import { devtools } from 'zustand/middleware';
    
    interface IStore {
      count: 0;
      increment: () => void;
      decrement: () => void;
    }
    
    const useStore = create<IStore>()(
      devtools((set) => ({
        count: 0,
        increment: () => set((state) => ({ count: state.count + 1 })),
        decrement: () => set((state) => ({ count: state.count -1 })),
      })),
    );
    
    export default useStore;
    
    // counter.tsx
    const Counter = () => {
      const count = useStore(state => state.count);
      const increment = useStore(state => state.increment);
      const decrement = useStore(state => state.decrement);
      return (
        <h3>{count}</h3>
        <button onClick={increment}>Up</button>
        <button onClick={decrement}>Down</button>
      );
    };
    
    export default Counter;

    4.2 jotai

    // counter.tsx
    import { atom, useAtom } from 'jotai';
    
    const countAtom = atom(0);
    
    const Counter = () => {
      const [count, setCount] = useAtom(countAtom);
      const increment = () => setCount((prev) => prev + 1);
      const decrement = () => setCount((prev) => prev - 1);
    
      return (
        <h3>{count}</h3>
        <button onClick={increment}>Up</button>
        <button onClick={decrement}>Down</button>
      );
    };
    
    export default Counter;

    여기에서 소개한 것 이외에도 zustand(persist, log 등...)와 jotai(selectAtom, focusAtom 등...)에는 다양한 기능들이 많이 존재한다.

    위 내용을 참고하여 자신에게 맞는 라이브러리를 선택해서 사용해보기를 바란다.

     

     

    반응형

    댓글

Designed by Tistory.