学习 zustand
- https://github.com/pmndrs/zustand
- 告别繁杂的状态管理:Zustand 的简洁之道
- Zustand 状态库:轻便、简洁、强大的 React 状态管理工具
- 关于 zustand 的一些最佳实践
代码库 https://gitee.com/nian_zuo_chen/learnrect/tree/master/zustand
安装
npm install zustand
常用
create创建一个storeset函数修改store内容get函数,获取当前store中内容store.getState()静态获取当前store的所有内容store.subscribe(listener)订阅store变更,任意一个值变更,都会执行listeneruseShallow可以开启浅比较,对象属性变化不触发
中间件
subscribeWithSelector在创建store时候增加,允许订阅的时候增加选择器,来限制监听的范围listener中返回的数据和选择器选择的内容一致。devtools在创建store时候增加,结合redux-dev-tools浏览器插件可以查看 store 变化- 处理持久化,
persist开启持久化,createJSONStorage使用JSON.stringify和JSON.parse把值设置为JSON字符串进行存取
疑问
-
zustand.set的返回值直接覆盖全部 state 还是做数据合并到 state 中?
由第二个参数控制,默认是 false 标识数据合并,当返回 true 时候,是直接覆盖。 -
当一次从
store中获取多个数据时候,建议使用zustand/react/shallow有啥用?
可以进行浅比较,避免没必要的渲染,和所有的浅比较一样,也会引入数据变化无感知的困惑,可以结合devtools来检查 -
对比
UpdateObj.tsx、UpdateObj2.tsx和ShallowEqual.tsx中获取store数据的方式,为什么只有UpdateObj.tsx可以监听到变化?UpdateObj.tsx、UpdateObj2.tsx都没有使用useShallow
但是UpdateObj2.tsx中(state) => stat.user每次返回的都是store中的user,所以对组件而言路径地址没变,所以不触发刷新。
而UpdateObj.tsx中(state) => ({user: stat.user})每次返回的都是一个新的{user: xxx}对象,地址一直在变,所以触发刷新UpdateObj.tsx和ShallowEqual.tsx获取数据一样,每次都返回一个新的{user: xxx}对象,但是useShallow内的shallow算法是Object.keys一致,以及第一层的obj[key]的值一致(使用Object.is比较),就算做未变更,所以不触发刷新。在这两个组件中{user: xxx}虽然是两个对象,但是它们kyes一样都是["user"],然后指向的都是stroe.user这个地址一致,所以算作未变化。这要小心使用呀。shallow.ts 源码