이 middleware는 기존 zustand의 subscribe를 확장시킨 middleware입니다. parameter를 보면
https://github.com/pmndrs/zustand/blob/main/src/middleware/subscribeWithSelector.ts#L32C6-L37C9 해당 링크 참조
(
selector: (state: T) => U, // << 상태 선택 array, object 다가능
listener: (selectedState: U, previousSelectedState: U) => void, << 선택된 상태값 출력
options?: {
equalityFn?: (a: U, b: U) => boolean,// 자신만의 비교 함수가 있는경우 사용
fireImmediately?: boolean
}
)
// src/store/user.type.ts
export interface UserState {
id: number;
userID: string;
userName: string;
age: number;
email: string
}
export interface UserAction {
fetchUserData: () => Promise<void>
setUserID: (data: string) => void
setUserName: (data: string) => void
resetUser: () => void
}
export interface UserStore extends UserState, UserAction {}
// src/store/user.ts
import {create} from 'zustand'
import {UserState, UserStore} from 'user.type.ts'
import { subscribeWithSelector } from 'zustand/middleware';
const defaultState = {
id: -1,
userID: '',
userName: '',
} as Omit<UserState, 'age' | 'email'>
export const useUserStore = create<UserStore>((set, get) => ({
...defaultState,
age: 0,
email: '',
fetchUserData: async () => {
// react-query를 구현하기 싫고, axios 또는 fetch로도 충분한 경우 이렇게 사용하고
// react-query를 사용할 경우 setUser(data:UserState 또는 사용자 정의 타입) 이런식으로 구현해서 사용하면됩니다.
// 어느 한것에 제한되려고 하지마세요. 자신의 성장을 막는 길입니다.
..... // 사용자 정보 호출하는 코드
},
setUserID: (data) => set({userID: data}),
setUserName: (data) => set({userName: data}),
}))
// src/pages/Home.tsx
useEffect(() => {
const unsubscribeForUserStore = useUserStore.subscribe(
(state) => [state.id, state.userID],
(value, prevValue) => {
console.log('변경된 값 :', value, '이전 값 :', prevValue)
}
)
return () => {
unsubscribeForUserStore(); // 이것이 없다면, home 페이지를 접속시마다 event가 중첩하여생성됨. 위에서 생성된 subscribe 이벤트를 취소
}
}, [])
이런식으로 구현이 가능하며, react native에서는 아주아주 유용하게 사용할 수 있죠. (예를들면 백그라운드 데이터라던지 등등등)