zustand
zustand 是一个 React 的轻量级状态管理工具库,用起来非常方便,不仅支持多模块创建状态管理,还可以使用 hook + selector 的方式,在组件内去获取所需的状态变量,我个人是感觉跟 Vue Pinia 有点相似,以下是一个简单的小例子,展示 zustand 的基本使用~
点击按钮的时候,会通过 increase方法去修改状态管理内部的 count。
按需重渲染
什么是按需重渲染?就比如当 count 变化时,只有需要使用到 count 的组件才会重新渲染,没用到 count 的就不用重渲染,减少不必要的渲染~
就比如我按了按钮之后,只有 Counter 这个组件会重渲染,而 App 却不会:
因为 count 只被 Counter 组件所选择到了,所以当count变化时,Counter 会重渲染:
源码实现
实现 create:
我们可以借着上面的代码例子,来一步步实现 zustand 的源码,先把引入的代码给注释掉,接下来我们自己来实现 create。
其实 zustand的源码量非常至少,并且也很容易读懂,无非就分成几步:
(1) 声明一个 create 函数,用来创建状态管理
(2) 维护一个状态管理 state,用来存放状态变量
(3) 声明两个函数 set、get,一个是设置
(4) 维护一个订阅集合 subscribe,收集订阅方,且当 set的时候,通知 subscribe 中的所有订阅方
(5) 准备一个 hooks 返回给使用者,并且需要准备一些材料,包括set、get、订阅入口
以上就实现了 create这个函数~
实现 _useStore
接下来实现 _useStore,其实他就做一件事:对比一下被选择的值,对比他修改前后是否相等,不相等的话就强制重渲染本组件。
强制重渲染可以巧妙借助useReducer这个内置 hooks 来实现::
达到效果
现在已经达到了我们想要的效果了~
并且当 count 变化时,也只会重渲染 Counter 组件~
代码优化
其实 _useStore的代码还可以再优化一些,我们可以借助 React 的内置 hooks,useSyncExternalStore 来简化我们的代码
这个 hooks 会自动传一个比较函数给 subscribe,并且第二个参数函数返回的值改变时,会触发这个比较函数~