当前位置: 首页 > news >正文

【前端】【React】【Zustand】[特殊字符] Zustand 系统学习大纲(实战版)

📚 Zustand 系统学习大纲(实战版)

1️⃣ 基础知识

1.1 安装

npm install zustand

使用场景

  • 任何 React 项目中使用轻量级全局状态管理

优化建议

  • 不需要单独安装中间件,所有插件均内置

1.2 创建 store

import create from 'zustand'interface CounterState {count: numberincrement: () => void
}export const useCounterStore = create<CounterState>((set) => ({count: 0,increment: () => set((state) => ({ count: state.count + 1 }))
}))

使用场景

  • 管理单个模块状态,如计数器、表单状态

优化建议

  • 拆分 store 模块,避免单 store 过大
  • 使用 TS 类型约束,避免动态访问属性报错

1.3 声明属性

interface StoreState {name: stringitems: string[]loading: boolean
}

使用场景

  • 存储基本类型、数组、对象、异步状态

优化建议

  • 对象/数组修改使用 setter 或 immer 避免引用丢失
  • 异步状态建议添加 loading / error 字段

1.4 声明方法

setName: (newName: string) => set({ name: newName })
fetchItems: async () => {set({ loading: true })try {const res = await fetch('/api/items')const data = await res.json()set({ items: data })} catch (e) {console.error(e)} finally {set({ loading: false })}
}

使用场景

  • 同步修改字段
  • 异步请求更新状态

优化建议

  • 异步方法需处理 loading / error
  • 避免直接修改对象引用

2️⃣ 页面中使用 store

2.1 单字段订阅

const count = useCounterStore(state => state.count)

使用场景

  • 页面只依赖单个字段
    优化建议
  • 精准订阅字段,减少组件重渲染

2.2 解构整个 store

const { count, increment } = useCounterStore()

使用场景

  • 页面需要同时使用多个字段和方法
    优化建议
  • 小心对象引用变化导致整组件刷新

2.3 批量订阅

const [count, items] = useCounterStore(state => [state.count, state.items])

使用场景

  • 需要同时获取多个字段
    优化建议
  • 只订阅必要字段
  • 对象/数组变化会触发刷新

2.4 非组件中获取

useCounterStore.getState().increment()
const currentCount = useCounterStore.getState().count

使用场景

  • 在 utils 或事件回调中访问 store
    优化建议
  • 避免绕过 React 响应式

2.5 订阅变化

useCounterStore.subscribe(state => state.count,newCount => console.log('count updated', newCount)
)

使用场景

  • 需要监听某字段变化进行副作用
    优化建议
  • 精准订阅单字段,避免全局订阅

3️⃣ 插件系统(Middleware)

3.1 DevTools

import { devtools } from 'zustand/middleware'const useStore = create(devtools((set) => ({count: 0,increment: () => set(state => ({ count: state.count + 1 }))
}), { name: 'counter' }))

使用场景

  • 调试状态变化,查看 action 历史

优化建议

  • 为每个 action 自定义名称
  • 仅在开发环境启用 DevTools

3.2 Persist

import { persist } from 'zustand/middleware'const useStore = create(persist((set) => ({ count: 0, increment: () => set(state => ({ count: state.count + 1 })) }),{ name: 'counter-storage', getStorage: () => localStorage })
)

使用场景

  • 页面刷新后仍需保持状态
  • 用户数据、表单输入缓存

优化建议

  • 使用 partialize 选择性持久化
  • 避免大对象直接写入 localStorage

3.3 Immer

import { immer } from 'zustand/middleware/immer'const useStore = create(immer((set) => ({items: [] as string[],addItem: (item: string) => set(state => { state.items.push(item) })}))
)

使用场景

  • 对对象/数组直接修改而不破坏响应式

优化建议

  • 避免频繁创建新对象,提升性能

3.4 多中间件组合

import { devtools, persist, immer } from 'zustand/middleware'const useStore = create(devtools(persist(immer((set) => ({count: 0,increment: () => set(state => { state.count += 1 })})),{ name: 'counter-storage' }))
)

使用场景

  • 同时需要 DevTools、持久化和 Immer

优化建议

  • 中间件顺序重要:immer → persist → devtools
  • 避免重复包装

4️⃣ 优化与升级

4.1 派生状态

const doubleCount = useCounterStore(state => state.count * 2)

使用场景

  • 页面展示需要派生数据
    优化建议
  • 不存 store,避免冗余
  • 可用 useMemo 缓存计算

4.2 精准订阅

const itemCount = useStore(state => state.items.length)

使用场景

  • 对象/数组变化避免全量刷新
    优化建议
  • 对数组/对象修改使用 Immer 或新对象替换

4.3 多 store 组合

  • 拆模块,按业务功能管理状态
  • 页面按需引入

优化建议

  • 避免单 store 过大
  • 多 store 更易扩展和维护

4.4 TypeScript 类型约束

interface CarbonData { total: number; categories: string[] }
interface StoreState { carbonData: CarbonData; setCarbonData: (data: CarbonData) => void }

使用场景

  • 确保状态与方法类型安全

优化建议

  • 明确所有字段和方法类型,避免运行时错误

4.5 持久化选择性字段

partialize: (state) => ({ carbonData: state.carbonData })

使用场景

  • 只存储必要数据
    优化建议
  • 减少 localStorage 占用
  • 可结合 redux-devtools 调试

4.6 异步状态管理

  • 管理 loading/error
  • 缓存 API 数据
  • 避免直接在组件中 fetch

优化建议

  • 使用 store 封装 API 请求
  • 返回类型统一,方便组件使用


文章转载自:

http://rbIC5tR9.cgstn.cn
http://0jNuwzQz.cgstn.cn
http://pOY1C6iH.cgstn.cn
http://0HlR16L2.cgstn.cn
http://t8irc7y3.cgstn.cn
http://bjIjDr6s.cgstn.cn
http://SRRPfiL2.cgstn.cn
http://quv4KtMB.cgstn.cn
http://cz4A7Wl3.cgstn.cn
http://4uDVismi.cgstn.cn
http://4jUdFk8T.cgstn.cn
http://bmChBcHu.cgstn.cn
http://oCa1z56U.cgstn.cn
http://pVNQLEMc.cgstn.cn
http://2WQaasCg.cgstn.cn
http://OrCxtt7k.cgstn.cn
http://iAxybqw6.cgstn.cn
http://Bvf6NWbJ.cgstn.cn
http://COtPouDi.cgstn.cn
http://vXN2qsSL.cgstn.cn
http://zGbEM7WQ.cgstn.cn
http://Yqr6k8yT.cgstn.cn
http://cBMCDMsx.cgstn.cn
http://meWZlq31.cgstn.cn
http://eapzM71M.cgstn.cn
http://MfX05D9w.cgstn.cn
http://AuNRfe8p.cgstn.cn
http://fYbw8Feb.cgstn.cn
http://XRnD2VPs.cgstn.cn
http://Tjaplup4.cgstn.cn
http://www.dtcms.com/a/388372.html

相关文章:

  • 在测试接口时,遇到关于时间参数的传参时,遇到类型编译器无法转换的解决方案
  • 晶圆厂为什么都采用高架地板?
  • unsloth 笔记:微调mistral-7b(纯文本数据集)
  • 【vim,Svelte】怎样使用 vim 编辑 Svelte 那些奇奇怪怪名字的文件?
  • 【AOI基板外观缺陷检测软件】基于Halcon+C#开发的AOI基板外观缺陷检测软件,全套源码,开箱即用
  • htb academy笔记-module-Password Attacks(一)
  • Java程序设计:顺序结构与分支结构
  • 铺满式水印添加教程!水印如何铺满整个详情页页面?
  • 基于SpringBoot+Vue.js开发的医疗器械管理系统
  • 职业定位:用 “能力 - 兴趣 - 需求” 模型找到赛道
  • Caffeine Expiry
  • 【C++项目】C++11重构muduo库
  • 如何选择靠谱的防伪溯源系统公司?
  • 线程池 相关知识
  • 搭建CI/CD 流水线简单说明
  • 大Key与热Key详解:概念、危害与解决方案
  • Java中的自动拆装箱原理
  • Android 入门笔记(2)
  • 程序员内功之成长性思维
  • vLLM 和 SGLang 是两个近年来备受关注的开源项目
  • CMake进阶: 路径处理指令join_paths和cmake_path
  • 算法简略速记手册
  • C语言(长期更新)第17讲内存函数
  • 【CSP-S】 基础知识与编程环境
  • Python HTTPS 教程 如何发送 HTTPS 请求、解决证书错误、实现抓包与网络调试全攻略
  • 【Cesium 开发实战教程】第五篇:空间分析实战:缓冲区、可视域与工程测量
  • 告别塑料感!10分钟学会基础材质调节
  • CSS Modules 和 CSS-in-JS比较
  • threejs(三)模型对象、材质
  • (自用)vscode正则表达式(正则表达式语法大全)vocode正则化(注意正则化和正则表达式不是一个概念)