بنقرة واحدة
zustand
Zustand 5 最佳實踐指南。當需要建立 store、設計 selector、使用 middleware (persist/immer/devtools)、或處理 React 狀態管理時使用。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Zustand 5 最佳實踐指南。當需要建立 store、設計 selector、使用 middleware (persist/immer/devtools)、或處理 React 狀態管理時使用。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | zustand |
| description | Zustand 5 最佳實踐指南。當需要建立 store、設計 selector、使用 middleware (persist/immer/devtools)、或處理 React 狀態管理時使用。 |
基於 2025/5 知識。基準版本:zustand ^5。v5 後
create必須用 curry 形式才能得到 TypeScript 正確推論。
import { create } from 'zustand'
type CubeState = {
facelets: string
history: string[]
applyMove: (move: string) => void
reset: () => void
}
export const useCubeStore = create<CubeState>()((set, get) => ({
facelets: 'UUUUUUUUU...',
history: [],
applyMove: (move) => set((s) => ({
facelets: applyToFacelets(s.facelets, move),
history: [...s.history, move],
})),
reset: () => set({ facelets: 'UUUU...', history: [] }),
}))
注意 create<T>()(...) 的雙括號——curried 形式。
// ❌ 整個 state 都訂閱,任何變動都 re-render
const store = useCubeStore()
// ✅ 只訂閱需要的
const facelets = useCubeStore((s) => s.facelets)
// ✅ 多個值用 useShallow(避免物件每次新建觸發 re-render)
import { useShallow } from 'zustand/react/shallow'
const { facelets, history } = useCubeStore(useShallow((s) => ({
facelets: s.facelets, history: s.history,
})))
規則:selector 絕對不要回傳新物件/陣列而沒用 shallow。
import { persist, devtools, subscribeWithSelector } from 'zustand/middleware'
import { immer } from 'zustand/middleware/immer'
export const useStore = create<State>()(
devtools(
persist(
immer((set) => ({
items: [],
add: (x) => set((s) => { s.items.push(x) }), // immer 可 mutate
})),
{ name: 'cube-storage', partialize: (s) => ({ items: s.items }) },
),
),
)
persist:自動存 localStorage;用 partialize 篩選要存的欄位devtools:Redux DevTools 整合immer:允許 mutate 寫法(方塊 state 很適合)subscribeWithSelector:store.subscribe((s) => s.x, callback) 選擇性訂閱useCubeStore.getState().facelets // 讀
useCubeStore.setState({ facelets: '...' }) // 寫
useCubeStore.subscribe((s) => console.log(s.facelets)) // 訂閱
適合在非 React 環境(worker、event handler 外部模組)使用。
type CubeSlice = { facelets: string; applyMove: (m: string) => void }
type UISlice = { panel: 'learn' | 'scan'; setPanel: (p: ...) => void }
const createCubeSlice: StateCreator<CubeSlice & UISlice, [], [], CubeSlice> = (set) => ({
facelets: '...',
applyMove: (m) => set((s) => ({ /* ... */ })),
})
export const useStore = create<CubeSlice & UISlice>()((...a) => ({
...createCubeSlice(...a),
...createUISlice(...a),
}))
(s) => ({ a: s.a }) 每次新物件 → 用 useShallow。set((s) => ...) 函式形式,別 set({ x: get().x + 1 })。onRehydrateStorage 或 useStore.persist.hasHydrated() 檢查。create<T>() 的 ()。beforeEach 裡 useStore.setState(initialState, true) 全量覆寫。React Compiler 會 memo 元件,但 Zustand 的 selector 訂閱機制照樣工作。不需要特別處理。
cubejs (Rubik's Cube solver, Kociemba two-phase) 使用指南。當需要實作魔術方塊自動解法、狀態字串序列化、或 scramble 產生時使用。
msw-fetch-mock 套件使用指南(搭配 MSW v2 + Vitest)。當需要 mock HTTP 請求、測試 fetch 呼叫、驗證 API 互動時使用。
React 19 最佳實踐指南。當需要撰寫 React 元件、使用 Hooks、處理狀態管理、或搭配 TypeScript/Vite 開發時使用。
React Three Fiber (R3F) + Three.js + drei 最佳實踐。當需要建立 3D 場景、處理相機/光照、互動事件、動畫、效能優化時使用。
TDD (Test-Driven Development) 最佳實踐指南,搭配 Vitest + React Testing Library。當需要撰寫測試、實踐 Red-Green-Refactor、設計測試結構時使用。應在開發新功能時主動套用。
Test Doubles 最佳實踐指南(Vitest + TypeScript)。當需要選擇 Mock/Stub/Fake/Spy/Dummy、或討論測試隔離策略時使用。