nanxiaobei/flooks

请教:是否更推荐model数据细粒度化?

jerry000lin opened this issue · 3 comments

作者你好,
感谢提供了如此简便的状态管理方式,有个疑问请教一下
阅读了一下源码,如果同一个model中state的数据不只一个,调用actions是无差别触发setState,这和react的context是一样的。
如果需要避免这种不必要的更新,可能需要细粒度的写model。这样在共用state较多的情况下,应该如何组织代码 ?
在假设细粒度成立的条件下,model数量将大大增加,不引入模块化的模块化的概念就变得很难管理了,当然也可以在开发者间写name的时候形成默契namespace。

总结一下,主要疑问是:
1、flook是否更适合细粒度的全局状态管理 ?
2、是否有在flooks中引入模块化概念的打算 ?

1、React 本身不是 Vue 那样通过监听的方式来触发更新,而是全量遍历组件树,触发更新就遍历整个树然后找不同,所以它本身的理念,就跟「细粒度」不是一脉的。

2、我理解你说的「细粒度」,应该是指比如用一堆 useState,然后每个 setXXX 去更新单个的 state XXX,但这样在 React 系统里也是触发整体树的遍历,跟直接用一个 state 对象而不是分开表示并没有什么区别。

3、flooks 目前的逻辑,可以理解为是 React class 组件中的模式,setState() 中传入一个 object state,仅此而已,同一 modal 的更新不会扩散到其它 model。

4、不太理解这里你这里的”模块化“是指什么情况,应该是指更细粒度,flooks 本身提供了模块化,但无法提供更细粒度的模块化,而且似乎也没有必要,这是 React 的更新方式决定的。

5、React 本身暴露了 useCallback()useMemo() 等接口来供开发者处理恶心的那部分,这也是 React 自身的机制所无法避免的糟粕。

关于触发更新,可以结合以下例子

https://codesandbox.io/s/sweet-tdd-ncrb8

如果将每个state分离到不同的model
比如这里counterStore里和counterStore里都有的count
这时候componentB里调用counterStore里的increment action,触发了counterStore里的count更新,并不会影响到使用couter1Store的componentA,所以componentA不会重新渲染。
具体的表现是console.log("reload");不会被执行,且react devtool没有高亮组件。

如果将很几个数据都放入一个model中
比如这里的counter1Store里有两个state:
const counter1 = {
state: {
count: 0,
count1: 0
},
actions: ({ model, setState }) => ({
increment1() {
const { count1 } = model();
setState({ count1: count1 + 1 });
}
})
};
当我在componentC里面触发counter1Store的increment1 action 使得 count1更新,componentA引用了counter1Store的count,但也重新渲染了。
具体的表现是console.log("reload");被执行,react devtool高亮组件。

这里 遍历组件树找不同 并不适用,这个问题react原生context api也有,所以 context 并没有干掉redux。

嗯明白了,这里确实存在可以优化的点。

这种情况目前可以在 ComponentA useModel() 中传入第二个参数 onlyActions(boolean),如useModel("counter1", true),但只是解决这个特定情况,没有完全解决问题。

后面会考虑提供用第二个参数定制用到的数据,以优化更新。

感谢反馈~