Slice pattern tổ chức Zustand store lớn thành modules độc lập — mỗi slice là StateCreator function, combine bằng spread trong create(); tên state không được trùng giữa các slices.
- Slice pattern giúp tổ chức store lớn thành các modules độc lập.
- Mỗi slice là một
StateCreatorfunction:const createCartSlice = (set, get) => ({ items: [], addItem: (item) => set(s => ({ items: [...s.items, item] })), clearCart: () => set({ items: [] }) }). - Tương tự:
const createUserSlice = (set) => ({ user: null, setUser: (u) => set({ user: u }), logout: () => set({ user: null }) }). - Combine trong create:
const useBoundStore = create((...a) => ({ ...createCartSlice(...a), ...createUserSlice(...a) })). - Với TypeScript: dùng
StateCreator<BoundStore, [], [], CartSlice>để type đúng — BoundStore là type của toàn bộ combined store, CartSlice là type của slice này. - Slice có thể cross-reference nhau qua
get():const createOrderSlice = (set, get) => ({ checkout: () => { const { items } = get(); const { user } = get(); return api.order(user.id, items) } }). - Lưu ý: tên state/action không được trùng giữa các slices — spread object sẽ overwrite.
Slice pattern organizes a large Zustand store into independent modules — each slice is a StateCreator function, combined via spread in create(); state names must not collide across slices.
- The slice pattern organizes a large store into independent modules.
- Each slice is a
StateCreatorfunction:const createCartSlice = (set, get) => ({ items: [], addItem: (item) => set(s => ({ items: [...s.items, item] })), clearCart: () => set({ items: [] }) }). - Similarly:
const createUserSlice = (set) => ({ user: null, setUser: (u) => set({ user: u }), logout: () => set({ user: null }) }). - Combine in create:
const useBoundStore = create((...a) => ({ ...createCartSlice(...a), ...createUserSlice(...a) })). - With TypeScript: use
StateCreator<BoundStore, [], [], CartSlice>to type correctly — BoundStore is the type of the full combined store, CartSlice is the type for this slice. - Slices can cross-reference each other via
get():const createOrderSlice = (set, get) => ({ checkout: () => { const { items } = get(); const { user } = get(); return api.order(user.id, items) } }).
Pitfall: state/action names must not collide between slices — spreading objects will overwrite duplicates.