본문 바로가기
react

zustand에 devtools 사용하기

by cactuslog 2024. 10. 27.
zustand에는 별도로 시각화 할 수 있는 devtools가 없기 때문에 redux devtools와 연동한다
이 때 redux 설치는 필요없다.

 

크롬에서 redux devtools 설치

https://chromewebstore.google.com/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=ko

 


store에 devtools 적용

import { create } from "zustand";
import { devtools } from "zustand/middleware";

type CounterStore = {
  count: number;
  increment: (by: number) => void;
  decrement: (by: number) => void;
};

const useCounter = create<CounterStore>()(
  devtools(
    (set) => ({
      count: 0,
      increment: (by) => set((state) => ({ count: state.count + by })),
      decrement: (by) => set((state) => ({ count: state.count - by })),
    }),
    { name: "counterStore" },
  ),
);
export default useCounter;

 

devtools의 name 옵션은 redux devtools에서 store를 구분하는데 사용한다.

 

테스트를 위해 아래 코드를 실행 후 devtools를 보면 모든 액션이 anonymous로 나온다

"use client";

import useCounter from "@/store/counter";
import { Button } from "@/components/ui/button";

const Page = () => {
  const { count, increment, decrement } = useCounter();

  return (
    <main>
      <div>
        <p>Count: {count}</p>
        <Button onClick={() => increment(1)}>increment</Button>
        <Button onClick={() => decrement(1)}>decrement</Button>
      </div>     
    </main>
  );
};
export default Page;

 

액션 이름 지정하기

const useCounter = create<CounterStore>()(
  devtools(
    (set) => ({
      count: 0,
      increment: (by) =>
        set(
          (state) => ({ count: state.count + by }),
          undefined,
          "counter/increment",
        ),
      decrement: (by) =>
        set(
          (state) => ({ count: state.count - by }),
          undefined,
          "counter/decrement",
        ),
    }),
    { name: "counterStore" },
  ),
);
  • set 함수의 두번 째 인자는 반드시 undefined로 설정한다
  • 두 번째 옵션인 replace를 설정해버리면 부분 업데이트가 아니라 덮어쓰기가 된다.
  • 예를 들어 { count: 0, name: 'Alice' }라고 할 때  set({ count: 1 }, true) 호출하면 name 필드는 사라진다.
  • 세번 째 옵션에 액션 이름을 지정하면 아래처럼 devtools에서 액션이 구분된다.

 


다른 미들웨어와 함께 사용하기

  • devtools 미들웨어는 setState에 추가적인 타입 정보를 추가하여 Redux DevTools에서 액션의 이름과 상태를 기록할 수 있게 한다.
  • 따라서 setState를 수정하기 때문에 항상 다른 미들웨어보다 마지막에 적용하는게 좋다.

 

localStorage를 이용하여 상태를 유지시키게 도와주는 persist와 같이 사용하기

const useCounter = create<CounterStore>()(
  devtools(
    persist(
      (set) => ({
        count: 0,
        increment: (by) =>
          set(
            (state) => ({ count: state.count + by }),
            undefined,
            "counter/increment",
          ),
        decrement: (by) =>
          set(
            (state) => ({ count: state.count - by }),
            undefined,
            "counter/decrement",
          ),
      }),
      { name: "counterStore" },
    ),
  ),
);