오늘은 요즘 핫하다는 리액트 상태관리 중 zustand에 대해 공부해 보고자 한다.
Zustand는 create 함수를 사용해 store를 정의하고,
useStore hook을 통해 상태와 메서드를 컴포넌트에서 사용할 수 있다.
// 패키지 관리자 yarn 사용
yarn add zustand
// 패키지 관리자 npm 사용
npm install zustand
// store.ts
Import { create } from 'zustand';
interface CountState {
count: number;
increase: () => void;
decrease: () => void;
}
// zustand store 생성
export const useCountStore = create<CountState>((set) => ({
count: 0, // 초기값
increase: () => set((state) => ({ count: state.count + 1 })),
decrease: () => set((state) => ({ count: state.count - 1 })),
}));
useCountStore를 사용하여 상태를 컴포넌트에서 관리할 수 있다.
import { useCountStore } from './store.ts';
const CountComponent = () => {
// zustand 상태와 메서드 사용
const { count, increase, decrease } = useCountStore();
return (
<div>
<h1>{count}</h1>
<button onClick={increase}>+</button>
<button onClick={decrease}>-</button>
</div>
);
}
export default CountComponent;
set 함수는 상태를 업데이트 하는데 사용된다.
주로 상태의 일부를 변경하고, 변경된 상태를 Store에 반영하는 역할을 한다.
새로운 상태나 상태 업데이트 로직을 인자로 받는다.
위에서 작성했던 코드로 set 함수의 역할을 확인해보겠다.
Import { create } from 'zustand';
interface CountState {
count: number;
increase: () => void;
decrease: () => void;
}
// zustand store 생성
export const useCountStore = create<CountState>((set) => ({
count: 0, // 초기값
increase: () => set((state) => ({ count: state.count + 1 })),
decrease: () => set((state) => ({ count: state.count - 1 })),
이 코드에서 set 함수는 상태 객체인 state를 받ㅇ아서 count 값을 증가시키는 방식으로 동작한다.
⭐️ set 함수의 형태
1) 객체 형태로 상태를 업데이트
특정 값을 즉시 업데이트 하는데 유용한 방식
set({ count: 10 })
2) 함수 형태로 상태를 업데이트
현재 상태를 기반으로 상태를 업데이트하는 함수 형태이다.
주로 이 방식으로 사용된다.
set((state) => ({ count: state.count + 1 }));
⭐️ set의 비동기 처리
Zustand의 set 함수는 내부적으로 비동기로 업데이트 한다.
하지만 비동기 함수를 반환하지는 않는다. 상태 변경 후 필요한 후속 작업이 있다면 set 호출 이후에 해당 작업을 직접 처리해야한다.
비동기 업데이트 예시
import create from 'zustand';
interface CountState {
count: number;
increaseAsync: () => Promise<void>;
}
const useCountStore = create<CountState>((set) => ({
count: 0,
increaseAsync: async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
set((state) => ({ count: state.count + 1 }));
},
}));
위의 코드에서는 IncreaseAsync 함수가 set을 사용하여 비동기 작업이 끝난 후 상태를 업데이트 한다.
zustand의 set 함수와 get함수도 같이 사용할 수 있다.
get은 현재 상태를 즉시 가져오고자 할 때 사용된다.
const useCountStore = create<CountState>((set, get) => ({
count: 0,
increase: () => {
const currentCount = get().count;
set({ count: currentCount + 1 });
},
}));