zustand快速上手(TypeScript)

zustand快速上手(TypeScript)
inkOrCloud注意:本文章基于zustand v5.0.7 ## 介绍 Zustand是一个轻量便捷的全局状态管理库,可在短时间内快速上手
对比
| 维度 | Redux | MobX | Zustand |
|---|---|---|---|
| 样板代码 | 多(action、reducer、selector) | 少(装饰器 / makeAutoObservable) | 极少(create(set => …) 即可) |
| 异步 | 需中间件(thunk/saga) | 原生 runInAction / flow | 原生 async/await |
| 绑定组件 | react-redux connect/useSelector | observer 高阶组件 | 直接 useStore 钩子 |
快速上手
安装
1 | npm i zustand |
创建状态
1 | interface UserStore { |
注意:必须返回新的对象引用,否则会导致组件不刷新,ts下建议使用create<>()()而不是create<>()
引用状态
1 | const ele:React.FC = () => { |
状态选择
不建议使用useUserStore()直接获取整个状态对象,这会导致状态中任意属性变化都触发组件重新渲染,建议使用Selector选择状态属性:
1
2const id = useUserStore(state => state.id)
const name = useUserStore(state => state.name)
因为zustand使用引用比较判断变化,所以直接使用结构赋值会导致State无限循环:
1
2
3const [id, name] = useUserStore(state => [id, name])
const {id, name} = useUserStore(state => ({id: state.id, name: state.id}))
//❌,每次渲染都会返回新的数组/对象,这会导致State无限循环1
2
3const [id, name] = useUserStore(useShallow(state => [id, name]))
const {id, name} = useUserStore(useShallow(state => ({id: state.id, name: state.id})))
//✅
使用immer中间件实现可变数据结构
安装immer
1 | npm i immer |
使用immer中间件
1 | import { create } from 'zustand' |
使用immer后修改状态不再需要返回新的state对象
使用persist中间件实现状态持久化
安装persist
1 | npm i persist |
使用persist
1 | import { create } from 'zustand' |
可以使用sessionStorange,localStorage(默认),cookie,indexeddb等持久化,只需在createJSONStrange中能够返回存储引擎的函数(存储引擎应具有getItem,setItem和removeItem方法)
其他问题
为什么TS下create()需要柯林化create<>()()
这是对microsoft/TypeScript#10571的变通方案
对于 1
2
3
4
5
6
7function case3<A, B, C>(b: string, c: boolean): A {}
// incorrect type of A - left unspecified:
example('thing');
// correct, but unnecessarily verbose - we already know that 'thing' is a string and true is a bool
example<number, string, boolean>('thing', true);1
2
3function case4<A>(): <B, C>(b:string, c:boolean) => A{}
example<number>()("thing", true)<B, C>(b:string, c:boolean) => A{}的函数,实现了A手动指定而B,C自动推断
zustand中create的定义: 1
2
3
4
5type Create = {
<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>): UseBoundStore<Mutate<StoreApi<T>, Mos>>;
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>) => UseBoundStore<Mutate<StoreApi<T>, Mos>>;
};
export declare const create: Create;

![[leetcode 3321][Go][有序集合]计算子数组的 x-sum II](https://s3.inkorcloud.top/image/2025/11/c9f55b2ecb04d16a57547b9f4de294ef.png)
![[leetcode 2589][Go][贪心]完成所有任务的最少时间](https://s3.inkorcloud.top/image/2025/11/b966fd1a91aa1ea098b86e6d778523c2.png)
![[leetcode 3234][Go]统计1显著的字符串的数量](https://s3.inkorcloud.top/image/2025/11/a72a47911de291f51cbb5902e4811c1f.png)
![[leetcode 1611][Go][位运算][记忆化搜索]使整数变为 0 的最少操作次数](https://s3.inkorcloud.top/image/2025/11/9715b5f3d8a7574ded3648767538558e.png)
![[leetcode 2528][Go][二分答案][差分数组][前缀和]最大化城市的最小电量](https://s3.inkorcloud.top/image/2025/11/fa0013722d9361b4383839722394dcf2.png)