Zustand
: 독일어로상태
라는 뜻을 가진 상태관리 라이브러리이다. 단순화된Flux
패턴을 사용하며,Hooks
에 기반에Redux
보다 상대적으로 쉽게 상태관리를 할 수 있다. (Jotai
개발자가 만듬)
$ npm install zustand
$ yarn add zustand
설치 후 따로 Provider
로 App
을 감싸주지 않아도 괜찮다
아래의 코드는 Zustand
의 store
를 만드는 가장 기본적인 형태의 코드이다.
import { create } from "zustand";
const useNameStore = create((set, get) => ({
name: "",
setName: (value: string) => set(() => ({ name: value })),
setToUpperName: () => set((state) => ({ name: state.name.toUpperCase() })),
}));
아래의 코드와 같이 Zustand
의 store
를 사용할 수 있다.
const { name, setName, toUpperName } = useNameStore();
위의 코드는 store
의 다른 요소가 변경되더라도 리렌더링이 일어난다.
하지만, 아래의 방식으로 store
를 사용한다면, 할당받은 속성의 변경시에만 리렌더링 되므로, 불필요한 렌더링을 막을 수 있다.
또한, 두번째처럼 구조분해할당을 할 경우에는 주소가 바뀌어 계속해서 리렌더링이 일어나게되며, shallow
를 적용하면 값 으로 비교하기에 불필요한 렌더링을 줄일 수 있다.
Zustand
는 old === new
에 해당되지 않을때 리렌더링을 함shallow copy
로 비교하기에 주소가 아닌 값을 비교 ! const nane = useNameStore(state => state.name);
// 구조분해할당
const { name, setName, setToUpperName } = useNameStore(
(state) => ({
name: state.name,
setName: state.setName,
setToUpperName: state.setToUpperName,
}),
shallow
);
아래의 코드처럼 type
을 지정해줄수도 있고, State
를 따로 빼내어 reset
로직을 추가해주었고, Actions
도 따로 분리하여 관리하도록 짠 코드이다.
(되도록, 아래의 customHook 형태를 export 하는 것을 권장함. 최적화, 가독성 측면 모두)
import { create } from "zustand";
export type State = {
name: string;
};
const initialState: State = {
name: "",
};
export type Actions = {
actions: {
setName: (value: string) => void;
resetName: () => void;
};
};
const useNameStore = create<State & Actions>((set, get) => ({
...initialState,
actions: {
setName: (value: string) => set(() => ({ name: value })),
resetName: () => set(() => initialState),
},
}));
/** export only custom hooks */
export const useName = () => useNameStore((state) => state.name);
export const useNameActions = () => useNameStore((state) => state.actions);
이러면 아래와같이 사용할 수 있다.
const name = useName();
const { setName, resetName } = useNameActions
...