الوسائط · فصل ٦

الوسائط الأربعة

devtools · redux · immer · subscribeWithSelector
🎯 الهدف: توصّل الأدوات، وتكتب بمسودة، وتسمع حقل واحد من بره React.

الوسيط دالة حوالين منشئ الحالة. تتركب. في TypeScript، devtools و persist و immer محتاجين نداء create بقوسين فاضيين قبل الدالة.

devtools

يربط المتجر بإضافة Redux DevTools من غير Redux. الحزمة المطلوبة @redux-devtools/extension. الافتراضي إن الوسيط شغّال في التطوير وواقف في الإنتاج.

devtools.js
import { create } from "zustand";import { devtools } from "zustand/middleware";const useCart = create()(  devtools(    (set) => ({      items: [],      add: (item) =>        set((state) => ({ items: [...state.items, item] }), false, "cart/add"),    }),    { name: "Cart", actionsDenylist: ["secret"] },  ),);

المعامل التالت لـ set اسم الأكشن في الخط الزمني. من غيره يظهر اسم عام. enabled يطفّي الربط. anonymousActionType نص الأكشن المجهول. store اسم تاني لو الأدوات بتعرض متجر واحد وعايز تبدّل. actionsDenylist أنماط تتخبى من العرض، والحدث لسه بيتبعت.

الإضافة تعرض متجر واحد في المرة. بدّل الاسم من قايمة الأدوات عشان تشوف التاني.

redux

لو الفريق عايز reducer نضيف و dispatch، الوسيط يركّبهم. الحالة الأولى أي قيمة غير دالة. dispatch يتضاف على المتجر.

redux-mw.js
import { redux } from "zustand/middleware";const useCart = create(  redux(    (state, action) => {      if (action.type === "cart/add") return { items: [...state.items, action.item] };      return state;    },    { items: [] },  ),);useCart.getState().dispatch({ type: "cart/add", item: { id: 1 } });

ده شكل Redux جوه المتجر. مش خطوة لازمة. الأكشن العادي أوضح في أغلب الشاشات.

immer

ثبّت حزمة immer، واستورد الوسيط من zustand/middleware/immer. جوه set تعدّل المسودة، والمكتبة تطلّع نسخة ثابتة.

immer.js
import { immer } from "zustand/middleware/immer";const useCart = create()(  immer((set) => ({    person: { name: "", city: "" },    rename: (name) => set((state) => { state.person.name = name; }),  })),);

من غير الوسيط، السطر ده تعديل في المكان والشاشة متحدثش. بالوسيط، المسودة مسموح تتعدل.

subscribeWithSelector

subscribe العادي يسمع كل تغيير. الوسيط يخلّيك تختار حقل. النداء ياخد سليكتور، وسامع، واختياري دالة مساواة و fireImmediately عشان أول نداء يوصل فورًا.

listen.js
import { subscribeWithSelector } from "zustand/middleware";const useCart = create()(subscribeWithSelector((set) => ({ items: [], add: (item) => set({ items: [item] }) })));const stop = useCart.subscribe(  (state) => state.items.length,  (len, prev) => console.log(prev, len),  { fireImmediately: true },);

التحديث العابر: السماع يكتب على عنصر في الصفحة أو ref، من غير setState في React. المؤشر أو الرقم السريع ما يعملش رسم للشجرة كلها.

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

🧠 اختبر نفسك
١) اسم الأكشن في DevTools يتحط فين؟
المعامل التالت لـ set، بعد false بتاعة الدمج.
٢) وسيط redux بيضيف إيه على الحالة؟
دالة dispatch. الـ reducer يرجّع الحالة الجديدة.
٣) ليه نسمع الطول ونكتب على ref؟
عشان التحديث السريع ما يعيدش رسم React كل مرة.