Javascript 使用备忘录与使用效果+;使用状态
使用Javascript 使用备忘录与使用效果+;使用状态,javascript,reactjs,typescript,react-hooks,Javascript,Reactjs,Typescript,React Hooks,使用usemo(例如用于密集函数调用)而不是使用useffect和useState的组合是否有任何好处 除了在第一次渲染时usemo的返回值为null之外,以下两个自定义挂钩在第一次渲染时的工作方式完全相同: useffect和useState 从“foo”导入{expensiveCalculation}; const useCalculate=someNumber=>{ const[result,setResult]=useState(null); useffect(()=>{ setRes
usemo
(例如用于密集函数调用)而不是使用useffect
和useState
的组合是否有任何好处
除了在第一次渲染时usemo
的返回值为null
之外,以下两个自定义挂钩在第一次渲染时的工作方式完全相同:
useffect和useState
从“foo”导入{expensiveCalculation};
const useCalculate=someNumber=>{
const[result,setResult]=useState(null);
useffect(()=>{
setResult(费用计算(someNumber));
},[someNumber]);
返回结果;
};
使用备忘录
从“foo”导入{expensiveCalculation};
const useCalculateWithMemo=someNumber=>{
返回UseMoom(()=>{
返回费用计算(someNumber);
},[someNumber]);
};
每次参数
someNumber
更改时,两者都会计算结果,usemo
的记忆在哪里?useffect和setState
将在每次更改时导致额外渲染:第一次渲染将“滞后”使用陈旧数据,然后它将立即使用新数据将附加渲染排队
假设我们有:
function expensiveCalculation(x) { return x + 1; }; // Maybe I'm running this on a literal potato
假设someNumber
最初为0:
版本立即呈现usemo
1
版本渲染useffect
,然后在组件渲染效果后运行,更改状态,并使用null
将新渲染排队1
someNumber
更改为2:
- 运行
并呈现usemo
3
版本运行,并再次呈现useffect
,然后效果触发,组件以正确的1
值重新运行3
expensiveCalculation
的频率而言,两者具有相同的行为,但useffect
版本会导致两倍的渲染,这会由于其他原因影响性能
另外,IMO的useMemo
版本更干净、可读性更强。它不会引入不必要的可变状态,并且运动部件更少
所以你最好用<代码> USEMEMO <代码>这里。 < P>我认为在选择它们之间有两个要点。
useffect
在呈现组件后调用,所以您可以从中访问DOM。例如,如果希望通过引用访问DOM元素,这一点很重要
useffect
保证在依赖项未更改时不会触发它<代码>使用备忘录不提供此类保证
正如你所说的,你应该考虑USEMEMO作为纯粹的优化技术。即使用常规函数调用替换UseMoom,您的程序也应该继续正常工作
useffect
+useState
可用于控制更新。甚至可以打破循环依赖关系并防止无限的更新循环。第一个在第一次渲染时将为null
,而第二个则不会。使用useMemo(例如,对于密集的函数调用)有什么好处吗?是的。您正在使用专门为此目的设计的挂钩。您列出的示例是useMemo最常见的真实示例。我认为useEffect在一些长时间运行的同步场景中也很有用。查看下面的沙箱。加载需要5秒,因为在长calc运行时useMemo保持渲染线程,而useEffect/useState one可以在calc运行时显示“微调器”,因此不会保持渲染:@Retsambesides optimization,我使用useMemo
而不是useState
+useffect
模式,因为渲染越多,调试就越困难。值得注意的是,React API文档提到,useMemo
不能保证在依赖项没有改变的情况下不会再次执行记忆化函数,因为React可能,将来,可以放弃缓存以提高性能。因此,如果记忆化函数有某种副作用,那么使用自定义挂钩可能会更明智。@Abhi更改道具会触发重新渲染。但是呈现的值基于[result,setResult]
状态,并且在useffect
运行之前不会调用setResult
,这会在渲染后发生。我们是否可以由此得出结论,在要计算的对象是async
的情况下,useffect
+useState
是正确的解决方案,因为该值无论如何在当前渲染中都不可用?相关的