组长让我把所有state都放Redux里

2021-07-30 15:38:00 浏览数 (1)

诡异的是,有多个群友说过类似的话:

他的同事/组长/领导...让他把所有state都放在Redux/Mobx...里

他们觉得不对,又不知道如何反驳。

今天我们来聊聊ReduxMobx等状态管理库和ReactVue等视图库之间的关系,希望能解决以上困惑。

产品的核心竞争力

如果你在电梯里遇到大领导,他问你:

小x,你们最近在做什么功能?

在电梯到达楼层前这短短2分钟,你该如何向大领导描述你们正在开发的功能呢?

我想你一定会介绍功能的大体逻辑,而不会聊功能里某个按钮的具体交互逻辑吧?

你会聊逻辑,而不是交互。因为逻辑是最重要的。

接下来我们通过一个小故事了解逻辑交互的关系。

逻辑与交互的关系

一天,老板让你开发文件上传功能。

开发过程其实就是处理「文件上传」这一领域相关的各种「状态」之间的关系(比如上传进度是否出错...)。

这部分状态,我们称为「领域状态」

逻辑开发完后,你基于各种「领域状态」编写「单元测试」

为了快速上线验证该功能是否有人用,你直接将其作为CLI工具发布。

几天后,经过数据验证,发现功能很受欢迎。于是你选择React作为视图库,基于之前的逻辑开发视图交互。

开发视图交互过程中需要处理视图相关各种「状态」(比如loading显隐打开关闭状态...)。

这部分状态,我们称为「视图状态」

可见,一款功能完备的产品包含「领域状态」「视图状态」。前者是必须的,后者是可选的。

视图库中的状态

说回ReactVue这样的视图库。

由于大部分视图库以「组件」作为模块边界,所以很自然的,「领域状态」「视图状态」被分割到不同组件中,但他们被分割的方式是完全不同的。

举个例子,一个完整的应用可以划分为很多组件:

「视图状态」角度来看这些组件:

对比上下两张图,组件1(黄色与绿色)大小一致,代表这是个交互逻辑自洽的纯组件(比如一个开关),他的交互逻辑不依赖其他组件。

一个开关

除了组件1,更多组件需要与其他组件形成大小互补,这代表他们的交互逻辑互相影响。

比如组件5的长宽受组件2、组件6、组件8影响,可能代表:组件5是个提示框,他是否弹出受2、6、8影响。

我们再从「领域状态」(蓝色部分)角度来看这些组件:

整个应用的逻辑分散在不同组件中,可能组件1的didMount回调中有一部分逻辑,组件3的useEffect回调中有一部分逻辑。

由于组件5是个提示框,只有提示效果,所以他不包含应用运转所必需的逻辑(即「领域状态」)。

什么时候使用状态管理

回到开篇,什么样的state(状态)应该放在状态管理里?

对于「视图状态」

  • 状态自洽的组件自己管理状态(如组件1)
  • 状态互相之间有影响的组件(如5与2、6、8)根据应用复杂度、组件间跨度决定

如果组件跨度比较近(如是兄弟关系),则公共状态可以提升到共同父组件。

如果组件跨度较远且应用不复杂,可以提升到共同的Context中。

如果应用复杂,再考虑状态管理方案。

对于「领域状态」,由于其天生以碎片形式分布在不同组件中,所以:

  • 简单的小应用可以任其分布在组件中,或者提升到共同的Context
  • 其他情况推荐用状态管理方案

甚至,对于「领域状态」中的子领域,可以在有「状态管理方案」的基础上再抽象出来单独处理。

比如对于「服务端请求的数据」这一「领域状态」,其性质更类似于「缓存」,在React中可以使用SWRReact Query处理。

总结

本文我们聊了状态的分类 —— 领域状态视图状态,对于这两种状态根据其特性有不同处理方案。

虽然一股脑将所有状态都交给Redux处理不是不行,但势必对项目的可读性、性能、扩展性造成影响。

学完本文能够说服同事/组长/领导最好。如果对方执意要Redux一把梭,对待这种执(憨)着(憨)的人,牢记四字箴言:


0 人点赞