المتجر · فصل ٥

الشرائح و combine

slices · combine · many stores
🎯 الهدف: تقسّم متجر كبير لشرائح، أو تسيب الاستنتاج لـ combine.

المتجر الواحد يتقسم دوال. كل دالة ترجع حقولها وأكشناتها، وتاخد نفس set و get.

slices.js
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 المقسوم لقوسين.

combine.js
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 من التاني. متتعملش دايرة: كل واحد مستني التاني وقت الإنشاء.

خلّصت الفصل لما

🧠 اختبر نفسك
١) ليه الوسيط مش جوه كل شريحة؟
عشان التخزين والأدوات تتطبق مرة على الحالة الكاملة، مش جزء يتخزن وجزء لأ.
٢) combine بيوفّر إيه في TypeScript؟
استنتاج الحالة والأكشنات من غير واجهة، ومن غير نداء create بقوسين فاضيين.
٣) إزاي شريحة تقرا حقل شريحة تانية؟
عن طريق get بعد ما المتجر يتلم.