Zustand 是什么?相比 Redux 有什么优势?
Zustand 是一个轻量级 React 状态管理库,API 简洁,不需要 Provider 包裹。
基本用法
import { create } from 'zustand'
const useStore = create((set, get) => ({
count: 0,
name: 'Tom',
increment: () => set(state => ({ count: state.count + 1 })),
decrement: () => set(state => ({ count: state.count - 1 })),
// 可以获取当前 state
reset: () => set({ count: 0, name: 'Tom' }),
// 异步操作不需要额外中间件
fetchUser: async (id) => {
const user = await api.getUser(id)
set({ user })
}
}))
// 组件中使用
function Counter() {
const count = useStore(state => state.count)
const increment = useStore(state => state.increment)
return <button onClick={increment}>{count}</button>
}
// 也可以解构(不会重渲染问题)
const { count, increment } = useStore()选择性订阅(性能优化)
// 只订阅 count,name 变化不触发重渲染
const count = useStore(state => state.count)
// 多个值
const { count, name } = useStore(state => ({
count: state.count,
name: state.name
}), shallow) // 需要 shallow 比较
// 使用 selector
const doubleCount = useStore(state => state.count * 2)中间件
import { create } from 'zustand'
import { persist, devtools } from 'zustand/middleware'
const useStore = create(
devtools( // Redux DevTools 支持
persist( // localStorage 持久化
(set) => ({
theme: 'light',
toggleTheme: () => set(state => ({
theme: state.theme === 'light' ? 'dark' : 'light'
}))
}),
{ name: 'app-storage' }
)
)
)跨组件共享
// 不需要 Provider,直接使用
// 任何组件都能访问
function Header() {
const theme = useStore(state => state.theme)
return <header className={theme}>...</header>
}
function Settings() {
const toggleTheme = useStore(state => state.toggleTheme)
return <button onClick={toggleTheme}>Toggle</button>
}对比 Redux
| 特性 | Redux | Zustand |
|---|---|---|
| 样板代码 | 多 | 极少 |
| Provider | 需要 | 不需要 |
| 不可变更新 | 必须 | 可选(可用 Immer) |
| 异步 | 需要 thunk/saga | 直接 async/await |
| 包体积 | ~2KB + RTK | ~1KB |
| TypeScript | 好(RTK) | 优秀 |
| 学习成本 | 中 | 低 |
对比 Context
// Context:任何 context 值变化,所有消费者都重渲染
const AppContext = createContext()
// ❌ 大量组件订阅同一个 context 会有性能问题
// Zustand:精确订阅
const count = useStore(state => state.count) // 只有 count 变化才重渲染什么时候用 Zustand
- 中小型 React 项目
- 不想用 Redux 的样板代码
- 需要全局状态但不想用 Context
- 需要精确的状态订阅
与其他轻量方案对比
- Jotai:原子化状态,适合细粒度
- Valtio:Proxy 代理,类似 Vue 的响应式
- Zustand:类似 Redux 的单一 store,但更简洁