动机
目前 React 状态管理的主流方案一般是 Redux 和 Mobx,Vue 则是 Vuex。
Vuex 和 Redux 非常类似,都是基于 Flux 架构衍生而来的。
Redux 是函数式的解决方案,需要写大量的样板文件,太过繁琐,所以很多人基于 Redux 进行了二次封装等来简化开发,例如 Dva 或者 Rematch。其中 Rematch 和 Vuex 使用体验上比较类似。
Mobx 则是通过 proxy 和 defineProperty 来劫持数据,对每个数据变动进行响应。
还有很多的状态管理工具,例如轻量级的状态管理工具 Unstated,被称为最简单的 React 状态管理工具。
等等这些状态管理工具在 React 16.7 以前都是不错的解决方案,解决了全局状态管理或者跨组件状态共享的痛点,有的注重于功能和范式,有的注重于易用性。
随着 Hooks 的横空出世,这些状态管理工具也纷纷推出自己的 Hooks 解决方案,例如 Redux Hooks、mobx-react-lite、unstated-next 等等。但在使用过程中,却感觉到有很多的局限性,例如 Redux 使用起来一贯的繁琐,而且对 TS 的支持很差。Mobx 的响应式编程上手比较复杂,而且 API 过于繁琐,Unstated 用自定义 Hooks 的方式,使用起来比较麻烦,而且还需要用到 context。
后来在适用 Hooks 的过程中,想到使用 useState 完全可以不借助于 context 就可以实现状态共享。
于是就参考 Redux 动手写了一个简单的 Demo1,但是发现效果并不好,一是对 TS 的支持过于复杂,有一定的缺陷,二是会遇到 Redux 一样的异步等问题。
后面我想到了另一种解决方案 Demo2,这种方式是完全基于类的编码方式,state 和 setState 的操作方式 与 React 的 Class Component 非常相似,上手容易,而且异步问题也非常容易解决。
在上面 Demo 的基础上,又参考 Redux 做了中间件支持,所以抽离出了 createStore。
为了与 Hooks 原则一致,把 useStore 单独抽离出来,后来发现,可以把 Hooks 相关逻辑都抽离到 useStore 方法中,抽离后,核心的 Store 与 Hooks 完全无关,然后 Vue 也支持 Hooks,所以也可以支持 Vue 使用。
这样,一个同事支持 React 和 Vue 的基于 Hooks 的状态管理工具的架构就完成了,希望大家尽情享用!