المتجر الواحد يتقسم دوال. كل دالة ترجع حقولها وأكشناتها، وتاخد نفس set و get.
const createItems = (set) => ({ items: [], add: (item) => set((state) => ({ items: [...state.items, item] })),});const createDiscount = (set, get) => ({ rate: 0, apply: (rate) => set({ rate }), total: () => get().items.reduce((sum, item) => sum + item.price, 0),});const useShop = create((...args) => ({ ...createItems(...args), ...createDiscount(...args),}));get في الشريحة يشوف الشرائح التانية، لأن الحالة اتلمّت قبل ما الأكشن يتنادى. عشان كده total يقرا items.
الوسيط يلف المتجر المجموع بس. لو حطيته جوه شريحة لوحدها، التخزين أو الأدوات تتطبق نص نص وتتلخبط.
في TypeScript، نوع الشريحة يتكتب كـ StateCreator على الحالة الكاملة. لو في وسيط، حط اسمه في خانة الـ mutators. راجع دليل الأنواع في الدوكس، لأن توقيع الدالة طويل.
combine
combine ياخد الحالة الأولى، ودالة تضيف الأكشنات. النوع يتستنتج، فمش محتاج واجهة، ومش محتاج نداء create المقسوم لقوسين.
import { create } from "zustand";import { combine } from "zustand/middleware";const useShop = create( combine({ items: [], rate: 0 }, (set) => ({ add: (item) => set((state) => ({ items: [...state.items, item] })), apply: (rate) => set({ rate }), })),);redux كمان بيعمل الحالة، فنفس الفكرة: من غير القوسين الزايدين. الوسيط اللي مش بيعمل الحالة، زي devtools و persist، في TypeScript محتاج create()() عشان الاستنتاج يكمّل.
أكتر من متجر
مش لازم كل حاجة في متجر واحد. سلة، وواجهة درج، يفضلوا متجرين صغيرين لو عمرهم مختلف. التنسيق يبقى إن أكشن في واحد ينادي getState من التاني. متتعملش دايرة: كل واحد مستني التاني وقت الإنشاء.