使用useMemo
(例如用于密集函数调用)而不是结合使用useEffect
和useState
有什么好处吗?
除了useMemo
的返回值是第一次渲染时的null
之外,这还有两个乍一看完全相同的自定义钩子(Hook):
https://codesandbox.io/s/nkxolxwzkj
useEffect和useState
import { expensiveCalculation } from "foo";
const useCalculate = someNumber => {
const [result, setResult] = useState<number>(null);
useEffect(() => {
setResult(expensiveCalculation(someNumber));
}, [someNumber]);
return result;
};
useMemoimport { expensiveCalculation } from "foo";
const useCalculateWithMemo = someNumber => {
return useMemo(() => {
return expensiveCalculation(someNumber);
}, [someNumber]);
};
两者都在每次参数someNumber
更改时都计算结果,useMemo
的提示在哪里? 最佳答案
useEffect
和setState
会在每次更改时导致额外的渲染:第一个渲染将“过时”与陈旧的数据“滞后”,然后它将立即将其他渲染与新数据排队。
假设我们有:
function expensiveCalculation(x) { return x + 1; }; // Maybe I'm running this on a literal potato
假设someNumber
最初为0:useMemo
版本立即呈现1
。 useEffect
版本渲染null
,然后在组件渲染效果运行之后,更改状态,并使用1
将新的渲染排队。 然后,如果我们将
someNumber
更改为2:useMemo
并呈现3
。 useEffect
版本将运行,并再次渲染1
,然后触发效果,并且组件将使用3
的正确值重新运行。 就
expensiveCalculation
运行的频率而言,两者具有相同的行为,但是useEffect
版本导致的渲染量是原来的两倍,这由于其他原因而对性能不利。另外,IMOt的
useMemo
版本更加简洁易读。它不会引入不必要的可变状态,并且运动部件更少。因此,最好只在此处使用
useMemo
。