zustand基础使用
# 安装
npm install zustand
# or
yarn add zustand
1
2
3
4
2
3
4
# 基础使用
# 创建 Store
import { create } from 'zustand';
const useStore = create((set, get) => ({
// 状态
count: 0,
user: null,
todos: [],
// 同步 action
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
reset: () => set({ count: 0 }),
// 异步 action
fetchUser: async (id) => {
const res = await fetch(`/api/users/${id}`);
const user = await res.json();
set({ user });
},
// 使用 get() 读取当前状态
addTodo: (text) => {
const todos = get().todos;
set({ todos: [...todos, { id: Date.now(), text, done: false }] });
},
toggleTodo: (id) => set((state) => ({
todos: state.todos.map(t =>
t.id === id ? { ...t, done: !t.done } : t
),
})),
}));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
在组件中使用
// 选择器:只订阅需要的状态片段
function Counter() {
const count = useStore((state) => state.count);
const increment = useStore((state) => state.increment);
// count 变化时重渲染,todos 变化时不重渲染
return <button onClick={increment}>{count}</button>;
}
function UserProfile() {
const user = useStore((state) => state.user);
const fetchUser = useStore((state) => state.fetchUser);
useEffect(() => { fetchUser(1); }, [fetchUser]);
if (!user) return <Skeleton />;
return <div>{user.name}</div>;
}
function TodoList() {
const todos = useStore((state) => state.todos);
const toggleTodo = useStore((state) => state.toggleTodo);
return (
<ul>
{todos.map(todo => (
<li key={todo.id} onClick={() => toggleTodo(todo.id)}
style={{ textDecoration: todo.done ? 'line-through' : 'none' }}>
{todo.text}
</li>
))}
</ul>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
添加类型提示
import {create} from 'zustand'
type BearType = {
besrs:number;
}
const useStore = create<BearType>() (()=>{
// 存储全局共享的数据或方法
return{
bears:0
}
})
export default useStore
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 同步修改状态 set
set 参数支持两种写法:
- 函数式:接收前置 state,适合依赖旧值更新
- 对象式:直接赋值,适合重置 / 固定值修改
# 修改Bears数量
import {create} from 'zustand'
type BearType = {
besrs:number;
incrementBears:()=>void;
}
const useStore = create<BearType>()((set)=>{
// 存储全局共享的数据或方法
return{
bears:0,
incrementBears:()=>set((preState)=>({bears:preState.bears + 1}))
}
})
export default useStore
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
在组件内
export const Father = ()=>{
// 调用useStore,同时提供一个选择数据的选择器
// state => 要访问的数据
const bears = useStore((state)=>state.bears)
const incrementBears = useStore((state)=>state.incrementBears)
return(
<Text>{bears}</Text>
<Button onClick={incrementBears}>incrementBears</Button>
)
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 重置Bears的数量
import {create} from 'zustand'
type BearType = {
besrs:number;
incrementBears:()=>void;
resetBears:()=>void;
}
const useStore = create<BearType>()((set)=>{
// 存储全局共享的数据或方法
return{
bears:0,
incrementBears:()=>set((preState)=>({bears:preState.bears + 1}))
resetBears:()=>set(()=>({bears: 0}))
}
})
export default useStore
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
在组件内
export const Father = ()=>{
// 调用useStore,同时提供一个选择数据的选择器
// state => 要访问的数据
const bears = useStore((state)=>state.bears)
const incrementBears = useStore((state)=>state.incrementBears)
const resetBears = useStore((state)=>state.resetBears)
return(
<Text>{bears}</Text>
<Button onClick={incrementBears}>incrementBears</Button>
<Button onClick={resetBears}>resetBears</Button>
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 根据step改变Bears的值
在store/index
import {create} from 'zustand'
type BearType = {
besrs:number;
incrementBears:()=>void;
resetBears:()=>void;
decrementBearsByStep:(step?:number)=>void;
}
const useStore = create<BearType>()((set)=>{
// 存储全局共享的数据或方法
return{
bears:0,
incrementBears:()=>set((preState)=>({bears:preState.bears + 1})),
resetBears:()=>set(()=>({bears: 0})),
decrementBearsByStep:(step = 1) => set((state)=>({bears:(state.bears - step)}))
}
})
export default useStore
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
在组件内
export const Father = ()=>{
// 调用useStore,同时提供一个选择数据的选择器
// state => 要访问的数据
const bears = useStore((state)=>state.bears)
const incrementBears = useStore((state)=>state.incrementBears)
const resetBears = useStore((state)=>state.resetBears)
const decrementBearsByStep = useStore((state)=>state.decrementBearsByStep)
return(
<Text>{bears}</Text>
<Button onClick={incrementBears}>incrementBears</Button>
<Button onClick={resetBears}>resetBears</Button>
<Button onClick={()=>decrementBearsByStep(5)}>decrementBearsByStep</Button>
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 异步修改bears的数量
在store/index
import {create} from 'zustand'
type BearType = {
besrs:number;
incrementBears:()=>void;
resetBears:()=>void;
decrementBearsByStep:(step?:number)=>void;
asyncIncrementBears:()=>void;
}
const useStore = create<BearType>()((set,get)=>{
// 存储全局共享的数据或方法
return{
bears:0,
incrementBears:()=>set((preState)=>({bears:preState.bears + 1})),
resetBears:()=>set(()=>({bears: 0})),
decrementBearsByStep:(step = 1) => set((state)=>({bears:(state.bears - step)})),
asyncIncrementBears:()=>{
setTimeout(()=>{
// get()可以获取store对象,并访问store的数据和方法
get().incrementBears()
},1000)
}
}
})
export default useStore
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
在组件内
export const Father = ()=>{
// 调用useStore,同时提供一个选择数据的选择器
// state => 要访问的数据
const bears = useStore((state)=>state.bears)
const incrementBears = useStore((state)=>state.incrementBears)
const resetBears = useStore((state)=>state.resetBears)
const decrementBearsByStep = useStore((state)=>state.decrementBearsByStep)
const asyncIncrementBears = useStore((state)=>state.asyncIncrementBears)
return(
<Text>{bears}</Text>
<Button onClick={incrementBears}>incrementBears</Button>
<Button onClick={resetBears}>resetBears</Button>
<Button onClick={()=>decrementBearsByStep(5)}>decrementBearsByStep</Button>
<Button onClick={asyncIncrementBears}>asyncIncrementBears</Button>
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 添加fishes相关的共享数据
全部状态放在单个 store 内,适合小型项目
import { create } from 'zustand'
type StoreState = {
// 熊模块
bears: number
incrementBears: () => void
resetBears: () => void
decrementBearsByStep: (step?: number) => void
asyncIncrementBears: () => void
// 鱼模块
fishes: number
incrementFishes: () => void
resetFishes: () => void
}
const useStore = create<StoreState>()((set, get) => ({
bears: 0,
incrementBears: () => set(prev => ({ bears: prev.bears + 1 })),
resetBears: () => set({ bears: 0 }),
decrementBearsByStep: (step = 1) => set(prev => ({ bears: prev.bears - step })),
asyncIncrementBears: () => {
setTimeout(() => get().incrementBears(), 1000)
},
fishes: 0,
incrementFishes: () => set(prev => ({ fishes: prev.fishes + 1 })),
resetFishes: () => set({ fishes: 0 })
}))
export default useStore
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
在组件内
export const Fishes = () => {
const fishes = useStore(state => state.fishes)
const incrementFishes = useStore(state => state.incrementFishes)
const resetFishes = useStore(state => state.resetFishes)
return (
<>
<p>鱼:{fishes}</p>
<button onClick={incrementFishes}>鱼+1</button>
<button onClick={resetFishes}>重置鱼数量</button>
</>
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 拆分store
- Multi-Store
- Single-Store
# 中间件
# persist
持久化
自动把 Zustand 状态保存到:
- localStorage(Web)
- AsyncStorage(React Native)
比如:
用户登录信息、token、设置项。
import { create } from "zustand";
import { persist } from "zustand/middleware";
const useUserStore = create(
persist(
(set) => ({
token: "",
setToken: (token:string) => {
set({
token,
});
},
}),
{
name: "user-storage",
}
)
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
React Native
import AsyncStorage from "@react-native-async-storage/async-storage";
const useUserStore = create(
persist(
(set)=>({
token:"",
setToken:(token)=>{
set({
token
})
}
}),
{
name:"user-storage",
storage:{
getItem: AsyncStorage.getItem,
setItem: AsyncStorage.setItem,
removeItem: AsyncStorage.removeItem,
}
}
)
)
// 新版推荐
import { createJSONStorage } from "zustand/middleware";
persist(
()=>({}),
{
name:"user",
storage:createJSONStorage(
()=>AsyncStorage
)
}
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# devtools
用于 Redux DevTools 调试
# immer
解决 Zustand 深层对象修改问题
# subscribeWithSelector
监听整个 store
store.subscribe()
// 使用:
import {
subscribeWithSelector
} from "zustand/middleware";
// 可以监听某个字段:
const useStore=create(
subscribeWithSelector(
()=>({
count:0,
name:""
})
)
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 实例
按照你的 TROPS 项目场景(BLE、token、设备状态、缓存)
用户信息 persist
BLE状态 网络状态 大型数据 subscribeWithSelector
比赛数据修改 immer
开发阶段 devtools
上次更新: 2026/07/27, 06:51:44