2024-01-09·6 min read
为什么我也说 useEffect 是不好的设计
基于项目经验分析 useEffect 的设计问题,以及为什么建议在项目中禁止使用它
ReactHooks
最近X上鱿鱼丝转发一条推,又发起了一波vue大战react的理念大战。
让人不禁感慨难道这就是前端娱乐圈的年更节目吗。
争论点又来到框架心智负担,作为框架用户,到底怎么才算更好用。
由于框架的学习使用,每个人的使用频率,场景,都截然不同,能不吵就有鬼了。
何必踩低一头,认为自己才是更高的那头。
python才是最好的语言(
不过争论结束的彩蛋就是,连续几波人都在抓着React连续两次执行UseEffect来喷。
- 人家就是这样设计的,dev模式下就会执行出两边
- 你需要保证执行两遍也能正确的解决所谓的副作用
因为这个之前有研究,所以让我想了一下自己的看法。
之前在用了Hook一段时间后,我就跟另外几个人讨论过这个useEffect的问题
最后结论就是,不要在项目中使用useEffect.
这个结论是基于一些历史hook代码维护,线上项目bug的经验得到的。
第一个重要的原因是
- 刚接触hook的react新手无法理解useEffect设计本身初衷,会出现滥用useEffect,混合使用的情况。
- 典型就是把useEffect当成类似 propsupdate, vue中的$watch的思路来使用,变成了一种订阅listener的写法
- 这种写法一旦混合几种if条件的业务逻辑,整个回调函数就会失去可读性和独立含义。而且极易出现未覆盖的边界条件,因为useEffect可不是只执行一次。
- 最糟糕的是这种代码需要从整个页面数据流去重构,在修bug的时候如果这么做,需要耗费大量心力。背负重构的心智和bug风险。
- 当里面如果依赖的函数使用了useCallBack,那整个复杂度会更高。这也是为什么我说useCallback也是一个失败的设计
- 第二种思路和前面类似,也是类似react class和vue带来的基础思路,更是页面设计中的标准思路,取代生命周期
- 取代生命周期的问题最大的问题是:看代码的人要理解你在模仿某个生命周期。其次的问题是在修业务需求bug的时候,会在里面融入一些其他的逻辑。
- 第二的问题就是它本来就不是为这个设计的,会出现大量的边界情况。
- 怎么办就是用成熟的类似ahooks的库来取代这部分逻辑,明确某些是useMount去做的。事实上你看他们模仿生命周期钩子的实现,也包含了一些边界情况处理
- 项目永远会有新人,也总有使用React的新人。与其科普一大堆抽象的自己都觉得勉强的概念,还不如直接禁止使用
- 第二点想说的其实就是维护相关的,其实前面已经提到了。这里指的维护一个是 抽象复用,一个是修bug/需求变更