Skip to main content

复杂状态处理:如何保证状态一致性?

原则一:保证状态最小化

在保证 State 完整性的同时,也要保证它的最小化。

某些数据如果能从已有的 State 中计算得到,那么我们就应该始终在用的时候去计算,而不要把计算的结果存到某个 State 中。

原则二:避免中间状态,确保唯一数据源

info

问题 1:函数体也是每次 render 都会执行,那么,需要每次都会 render 执行的语句是放在 无依赖的 useEffect 中呢,还是直接放在函数体中比较好呢?

讲解:这两种情况的语义是不一样的。useEffect 代表副作用,是在函数 render 完后执行。而函数体中的代码,是直接影响当次 render 的结果。

所以在写代码的时候,我们一定要理解每个 API 的语义,副作用一定是和当前 render 的结果没关系的,而只是 render 完之后做的一些额外的事情。

问题 1:老师,有两种写法,请问在性能方面是否后者优于前者?写法如下:


const handleIncrement = useCallback(() => setCount(count + 1), [count]);


const handleIncrement = useCallback(() => setCount(q => q + 1), []);

我的理解是这样的:后者只创建了一次函数,但是又调用了多次在 setCount 的回调函数。前者只会在 count 变化的时候创建新的回调函数。这样分析下来我又觉得两者没什么差异。我不是太清楚这两者的优缺点,希望得到老师的解答。

讲解:确实后者是更好的写法,因为 handleIncrement 不会每次在 count 变化时都使用新的。从而接收这个函数的组件 props 就认为没有变化,避免可能的性能问题。

但是有时候如果 DOM 结构很简单,其实怎么写都没什么影响。但两种代码实际上都是每次创建函数的,只是第二种写法后面创建的函数是被 useCallback 忽略的。