Zustand 是一个基于 Flux 原理实现的轻量级的状态管理库。截止到 2025年5月12日,Zustand 的最新版本是 5.0.4,Github 收藏数量为52.2k,npmjs周下载量为7m。
Zustand 应用示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import { create } from 'zustand';
const useStore = create(set => ({ count: 1, inc: () => set(state => ({ count: state.count + 1 })) }));
function Counter() { const { count, inc } = useStore(); return ( <div> <span>{count}</span> <button onClick={inc}>one up</button> </div> ); }
|
API
create
create 函数用于创建一个 store。
create 接受一个函数,这个函数接收一个 set 函数和 get 函数,用于更新状态和获取状态。返回一个 useStore hook,在组件中可以通过 useStore hook 来访问状态和调用状态更新函数。
1 2 3 4 5
| const useStore = create((set, get) => ({ count: 0, increase: () => set(() => ({ count: get().count + 1 })), decrease: () => set(() => ({ count: get().count - 1 })) }));
|
subscribe
subscribe 函数用于订阅 store 的变化。
subscribe 方法允许订阅状态的变化。当状态发生变化时,订阅的回调函数会被调用。
1 2 3 4 5 6 7 8 9 10 11 12
| const useStore = create(set => ({ count: 0, increase: () => set(state => ({ count: state.count + 1 })) }));
const unsubscribe = useStore.subscribe( state => state.count, count => console.log('Count changed to', count) );
unsubscribe();
|
destroy
destroy 函数用于销毁 store,清除所有订阅。
1 2 3 4 5 6
| const useStore = create(set => ({ count: 0, increase: () => set(state => ({ count: state.count + 1 })) }));
useStore.destroy();
|
setState
setState 函数用于直接更新 store 的状态,而不是通过定义的状态更新函数来更新状态。
1 2 3 4 5
| const useStore = create(set => ({ count: 0 }));
useStore.setState({ count: 10 });
|
getState
getState 函数用于直接获取 store 的状态。与 get 方法类似,但 getState 是在 store 上调用的。
1 2 3 4 5 6
| const useStore = create(set => ({ count: 0 }));
const currentState = useStore.getState(); console.log(currentState.count);
|
注意事项
- 状态更新函数可以是异步的
1 2 3 4 5 6 7 8
| const useStore = create(set => ({ data: null, fetchData: async () => { const response = await fetch('https://api.example.com/data'); const data = await response.json(); set({ data }); } }));
|
- zustand 支持使用中间件来扩展功能,常用的中间件包括:
- devtools: 与 Redux DevTools 兼容的中间件,可以方便地调试状态变化
1 2 3 4 5 6 7 8 9 10
| import create from 'zustand'; import { devtools } from 'zustand/middleware';
const useStore = create( devtools(set => ({ count: 0, increase: () => set(state => ({ count: state.count + 1 })), decrease: () => set(state => ({ count: state.count - 1 })) })) );
|
- persist: 持久化中间件,可以使用中间件将状态持久化到 localStorage 或 sessionStorage
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import create from 'zustand'; import { persist, createJSONStorage } from 'zustand/middleware';
const useStore = create( persist( set => ({ count: 0, increase: () => set(state => ({ count: state.count + 1 })), decrease: () => set(state => ({ count: state.count - 1 })) }), { name: 'count-storage', storage: createJSONStorage(() => sessionStorage) } ) );
|
- redux: Redux 中间件,可以将状态管理库与 Redux 库结合使用
1 2 3 4 5
| import { createStore, applyMiddleware } from 'redux'; import { createStore as createZustandStore } from 'zustand'; import { redux } from 'zustand/middleware';
const store = createZustandStore(redux(reducer, initialState, applyMiddleware(logger)));
|
避免将所有状态放在一个大 store 中,建议将状态拆分成多个小的 store,根据不同的功能模块来管理各自的状态
为状态提供合理的默认值,避免因状态未初始化而引起的错误。
避免不必要的状态变化,以减少组件的重新渲染次数
使用 useStore(state => state.count) 精确订阅状态的某一部分变化,避免 useStore.getState() 订阅所有状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| const useStore = create(set => ({ count: 0, increase: () => set(state => ({ count: state.count + 1 })), decrease: () => set(state => ({ count: state.count - 1 })) }));
const useCount = () => useStore(state => state.count);
function Counter() { const count = useCount(); const increase = useStore(state => state.increase); const decrease = useStore(state => state.decrease);
return ( <div> <h1>{count}</h1> <button onClick={increase}>Increase</button> <button onClick={decrease}>Decrease</button> </div> ); }
|