前言
笔者的React项目是在umi的基础上开发的,并主要使用的umi提供的@umijs/plugin-model 作为状态管理工具,但在项目开发过程中,有些时候在组件外使用全局状态,简单的方式是将需要使用的状态单独存储到localStroage中,在对应的地方获取调用,这种方式较为繁琐,因此萌生了自己写一个状态管理工具的想法。
plugin-model在umi启动时将数据全部存储到context中,脱离正常的渲染流,并使用自定义的 useModel 进行数据获取和更新;因为脱离的正常的渲染流,在useModel中调用useContext并不能获取到数据,因此plugin-model采用了发布订阅机制,在useModel调用时,写入对应的回调函数,当数据改变时,会分别调用相关的回调函数,对组件进行数据更新。
通过plugin-model的启发,我们可以将基于context的数据管理舍弃,直接采用js原始对象进行管理,并定义相关的hook,在数据更新时,直接通过发布订阅机制通知修改,数据管理方面因为不涉及到react,因此可以直接在react初始化之外使用相关数据。
基本代码已经实现,已经放到了下面的github中。
使用
使用createModule初始化一个状态模块,初始化完成后,会返回一个自定义hook方法,可以按照react hook的调用方式进行状态调用,也可以通过访问 方法属性直接调用或使用状态数据
状态定义
const useCustomStore = createModule({
// ... 相关定义
})
直接调用
// 获取属性
const a = useCustomStore.state.a;
// 调用方法
const fn = useCustomStore.fn();
const { fn } = useCustomStore;
fn();
hook形式调用
// 在react组件中采用hook形式调用
const App = () =>{
const store = useCustomStore();
return null;
}
// 支持selector,监听部分数据,进行性能优化
const App = () =>{
const customStore = useCustomStore((store)=>({
a: store.state.a,
fn: store.fn
}));
return null;
}
结束语
这个程序只是我自己的一个想法,实现了基础的代码,有很多的边界情况未考虑,并没有发布到npm上,如果大家有更好的想法,欢迎在评论区讨论。