Glittering's blog Glittering's blog
Home
  • 学习手册

    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)

Glitz Ma

前端开发工程师
Home
  • 学习手册

    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)
  • react基础

  • react原理

  • react全家桶

    • react全家桶概览
    • redux介绍
    • Zustand 实战总结
      • 一、Zustand 核心理念
        • ✅ 设计哲学
      • 二、基础入门
        • 1️⃣ 安装
        • 2️⃣ 创建第一个 Store
        • 3️⃣ 组件中使用
      • 三、进阶核心技巧
        • 🎯 1. 精准订阅(避免无效渲染)
        • 搭配浅比较
        • 🎯 2. 异步操作(请求接口)
        • 🎯 3. 中间件使用
        • persist(本地存储)
        • devtools(调试)
        • 🎯 4. 拆分模块(大型项目)
        • 模块合并
      • 四、高级实战技巧
        • 🔥 1. get() 读取最新状态
        • 🔥 2. subscribe 监听(非组件环境)
        • 🔥 3. immer 中间件(复杂对象)
        • 🔥 4. 重置 Store
      • 五、性能优化总结
        • ✅ 必做
        • ❌ 避免
      • 六、Zustand vs Redux 对比
      • 七、企业级最佳实践
        • 1️⃣ 状态分层
        • 2️⃣ 不要滥用全局状态
      • 八、常见坑总结
      • 九、实战项目结构示例
      • 🔟 终极总结
  • 《React18》学习笔记
  • react全家桶
mamingjuan
2025-09-30
目录

Zustand 实战总结

Zustand 是一个轻量、无样板代码(boilerplate)的 React 状态管理库。相比 Redux 更简单,相比 Context 更高效,非常适合中小型到中大型项目。


# 一、Zustand 核心理念

# ✅ 设计哲学

  • 极简 API
  • 基于 Hooks
  • 无 Provider(默认)
  • 支持中间件
  • 支持 TS 友好

核心思想:

用一个全局 store + hook 选择性订阅状态


# 二、基础入门

# 1️⃣ 安装

npm install zustand
1

# 2️⃣ 创建第一个 Store

import { create } from 'zustand'

const useCounterStore = create((set) => ({
  count: 0,
  increase: () => set((state) => ({ count: state.count + 1 })),
  decrease: () => set((state) => ({ count: state.count - 1 })),
}))
1
2
3
4
5
6
7

# 3️⃣ 组件中使用

function Counter() {
  const { count, increase, decrease } = useCounterStore()

  return (
    <>
      <div>{count}</div>
      <button onClick={increase}>+</button>
      <button onClick={decrease}>-</button>
    </>
  )
}
1
2
3
4
5
6
7
8
9
10
11
  • ✔ 自动订阅
  • ✔ 组件卸载自动取消订阅
  • ✔ 无 Provider

# 三、进阶核心技巧


# 🎯 1. 精准订阅(避免无效渲染)

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

只监听 count,其他字段变化不会触发重渲染。

# 搭配浅比较

import { shallow } from 'zustand/shallow'

const { count, increase } = useCounterStore(
  (state) => ({ count: state.count, increase: state.increase }),
  shallow
)
1
2
3
4
5
6

# 🎯 2. 异步操作(请求接口)

const useUserStore = create((set) => ({
  user: null,
  loading: false,
  fetchUser: async () => {
    set({ loading: true })
    const res = await fetch('/api/user')
    const data = await res.json()
    set({ user: data, loading: false })
  }
}))
1
2
3
4
5
6
7
8
9
10
  • ✔ Zustand 不限制 async
  • ✔ 无 thunk / saga 概念

# 🎯 3. 中间件使用

# persist(本地存储)

import { persist } from 'zustand/middleware'

const useStore = create(
  persist(
    (set) => ({
      theme: 'light',
      toggle: () => set((s) => ({ theme: s.theme === 'light' ? 'dark' : 'light' })),
    }),
    {
      name: 'app-storage',
    }
  )
)
1
2
3
4
5
6
7
8
9
10
11
12
13

# devtools(调试)

import { devtools } from 'zustand/middleware'

const useStore = create(
  devtools((set) => ({
    count: 0,
    inc: () => set((s) => ({ count: s.count + 1 }), false, 'inc')
  }))
)
1
2
3
4
5
6
7
8

可在 Redux DevTools 中查看。


# 🎯 4. 拆分模块(大型项目)

推荐结构:

store/
 ├── index.ts
 ├── user.ts
 ├── cart.ts
 └── theme.ts
1
2
3
4
5

# 模块合并

import { create } from 'zustand'
import { createUserSlice } from './user'
import { createCartSlice } from './cart'

export const useStore = create((...a) => ({
  ...createUserSlice(...a),
  ...createCartSlice(...a),
}))
1
2
3
4
5
6
7
8
  • ✔ 类似 Redux slice
  • ✔ 更清晰
  • ✔ 可维护性强

# 四、高级实战技巧

# 🔥 1. get() 读取最新状态

const useStore = create((set, get) => ({
  count: 0,
  double: () => {
    const current = get().count
    set({ count: current * 2 })
  }
}))
1
2
3
4
5
6
7

# 🔥 2. subscribe 监听(非组件环境)

const unsubscribe = useStore.subscribe(
  (state) => state.count,
  (count) => console.log('count changed:', count)
)
1
2
3
4

适用于:

  • 日志系统
  • websocket
  • 外部模块监听

# 🔥 3. immer 中间件(复杂对象)

import { immer } from 'zustand/middleware/immer'

const useStore = create(
  immer((set) => ({
    user: { name: '', age: 0 },
    updateName: (name: string) =>
      set((state) => {
        state.user.name = name
      }),
  }))
)
1
2
3
4
5
6
7
8
9
10
11
  • ✔ 可变写法
  • ✔ 内部自动 immutable

# 🔥 4. 重置 Store

const initialState = { count: 0 }

const useStore = create((set) => ({
  ...initialState,
  reset: () => set(initialState),
}))
1
2
3
4
5
6

# 五、性能优化总结

# ✅ 必做

  • 使用 selector
  • 使用 shallow
  • 拆分 store
  • 避免大对象直接返回

# ❌ 避免

  • 整个 state 解构
  • 在 store 里写复杂 UI 状态
  • 所有状态放一个 store

# 六、Zustand vs Redux 对比

对比 Zustand Redux
学习成本 低 高
模板代码 少 多
中间件 支持 强
适合项目 中小/中大型 中大型

# 七、企业级最佳实践

# 1️⃣ 状态分层

  • UI状态(本地)
  • 全局共享状态(Zustand)
  • 服务器状态(React Query)

推荐组合:

  • Zustand + React Query
  • Zustand + Vite
  • Zustand + Next.js

# 2️⃣ 不要滥用全局状态

判断标准:

  • 多组件共享?
  • 是否跨页面?
  • 是否需要缓存?

否则使用 useState。


# 八、常见坑总结

  • ⚠ StrictMode 下初始化两次
  • ⚠ persist 需要处理版本升级
  • ⚠ SSR 需避免状态污染
  • ⚠ 异步并发注意覆盖问题

# 九、实战项目结构示例

src/
 ├── store/
 │   ├── authStore.ts
 │   ├── productStore.ts
 │   └── index.ts
 ├── hooks/
 ├── pages/
 └── services/
1
2
3
4
5
6
7
8

# 🔟 终极总结

Zustand 适合:

  • ✔ 追求简单
  • ✔ 不想写 reducer
  • ✔ 不想配置复杂中间件
  • ✔ 希望极致开发体验

一句话总结:

小而美,够用且强大。

上次更新: 2026/02/25, 10:38:50
redux介绍

← redux介绍

Copyright © 2015-2026 Glitz Ma
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式