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" },
),
),
);
'react' 카테고리의 다른 글
Suspense를 활용한 SSR Architecture의 성능 개선 (0) | 2024.05.01 |
---|---|
useFormState hook으로 Form 상태를 다루자 (0) | 2024.03.10 |
shadcn/ui 를 활용하여 공통 컴포넌트를 쉽고 빠르게 ! (0) | 2024.03.05 |
nextjs 최신 버전 프로젝트 설정 (eslint, pretter) (0) | 2024.03.05 |
React 19 버전 canary (0) | 2024.03.05 |