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';

// 使用 create 创建一个 store, store 包含了状态和修改状态的方法
const useStore = create(set => ({
count: 1,
inc: () => set(state => ({ count: state.count + 1 }))
}));

function Counter() {
// 通过 useStore 访问状态和更新方法
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. 状态更新函数可以是异步的
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 });
}
}));
  1. 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) // (可选) 默认使用 localStorage
}
)
);
  • 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)));
  1. 避免将所有状态放在一个大 store 中,建议将状态拆分成多个小的 store,根据不同的功能模块来管理各自的状态

  2. 为状态提供合理的默认值,避免因状态未初始化而引起的错误。

  3. 避免不必要的状态变化,以减少组件的重新渲染次数

  4. 使用 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>
);
}