React에서 상태관리 툴 zustand 사용하기

zustand는 flux 원리를 따르는 가볍고 뛰어난 성능을 보여주면서도 사용하기 쉬운 쉬운 상태관리 툴이다.

🥕 다양한 hooks을 지원하기 때문에, React에 익숙한 사용자라면 더욱 더 쉽게 접근할 수 있다.

🥕 기존의 Context API의 단점인 Provider 내부의 렌더링 최적화 문제를 해결하고, 심지어 zustand는 provider로 감싸주지 않아도 되는 장점을 지닌다.

🥕 기존의 redux보다 더 간편한 설정이 가능하며 recoil보다 활발하게 업데이트와 이슈 활동이 이루어지고 있기 때문에 앞으로가 더 기대되는 라이브러리이다.

 

간단한 사용법

위에서 말했듯, zustand는 별다른 설정없이 사용할 수 있다.

create 함수를 통해서 상태와 상태를 변화시킬 함수를 작성한다.

import { create } from "zustand";

interface BearState {
  bears: number;
  increasePopulation: (by: number) => void;
  removeAllBears: () => void;
}

const useBearStore = create<BearState>((set) => ({
  bears: 0,
  increasePopulation: (by: number) =>
    set((state) => ({ bears: state.bears + by })),
  removeAllBears: () => set({ bears: 0 }),
}));

상태 bears는 increasePopulation에 의해서 증가되고, removeAllBears에 의해서 0으로 초기화된다.

위와 같이 상태와 상태를 변화시키는 함수를 생성할 수 있다.

내부 상태 값을 변경하기 위해서는 콜백함수의 인자로 주어지는 set 메서드를 사용한다.

또한, zustand는 내부에 immer를 내장하기에 불변성을 보장한다.

 

리액트에서 이 상태와 함수를 사용하고자 한다면, create로 생성한 useBearStore를 이용한다.

function App() {
  const {
    bears,
    increasePopulation,
    removeAllBears,
  } = useBearStore((state) => state);

  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      <h1>Hi : {bears}</h1>
      <button onClick={() => increasePopulation(123)}>increase</button>
      <button onClick={removeAllBears}>remove All</button>
    </div>
  );
}

useBearStore 함수 내부에 콜백함수를 통해서 원하는 상태나 함수를 가져올 수 있다.

 

비동기 처리하기

언제나 상태관리 툴을 사용할 때 고려하게 되는 것이 비동기 처리인데, zustand는 이 부분에 있어서도 상당히 간단하고 쉽게 작성할 수 있다.

import { create } from "zustand";

interface PictureState {
  imgSrc: string;
  getRandomImage: () => void;
}

const usePictureStore = create<PictureState>((set) => ({
  imgSrc: "",
  getRandomImage: async () => {
    const src = await fetch("https://picsum.photos/200/300");
    set(() => ({ imgSrc: src.url }));
  }
}));

function App() {
  const imgSrc = usePictureStore((state) => state.imgSrc);
  const getRandomImage = usePictureStore((state) => state.getRandomImage);

  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      <button onClick={getRandomImage}>get Img</button>
      {imgSrc ? <img src={imgSrc} alt="RI" /> : null}
    </div>
  );
}

export default App;

비동기 처리는 redux에서 복잡한 과정이 필요한 것과는 대조적으로 zustand에서는 async 함수를 사용하여 간단하게 구현할 수 있다.

위의 컴포넌트에서 버튼을 클릭하면, picsum.photos에서 랜덤으로 이미지를 가져오는 것을 확인할 수 있다.

 

 

또한, zustand는 미들웨어를 지원하므로 상태 업데이트 전후로 추가적인 기능들을 사용할 수 있다.

🥕 예를 들면, immer나 persist와 같은 미들웨어들이 있다.

 

https://github.com/pmndrs/zustand

 

GitHub - pmndrs/zustand: 🐻 Bear necessities for state management in React

🐻 Bear necessities for state management in React. Contribute to pmndrs/zustand development by creating an account on GitHub.

github.com