[英]useMemo vs. useEffect + useState
使用useMemo
(例如用於密集函數調用)而不是使用useEffect
和useState
的組合有useEffect
useState
?
這里有兩個自定義鈎子,乍一看完全相同,除了useMemo
的返回值在第一次渲染時為null
:
import { expensiveCalculation } from "foo";
function useCalculate(someNumber: number): number {
const [result, setResult] = useState<number>(null);
useEffect(() => {
setResult(expensiveCalculation(someNumber));
}, [someNumber]);
return result;
}
import { expensiveCalculation } from "foo";
function useCalculateWithMemo(someNumber: number): number {
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
版本導致兩倍的渲染,這對性能不利,因為其他原因。
另外,IMO 的useMemo
版本更清晰、更易讀。 它不會引入不必要的可變狀態並且具有更少的移動部件。
所以你最好在這里使用useMemo
。
我認為在它們之間進行選擇時,您應該考慮兩個要點。
useEffect
在組件渲染后調用,因此您可以從中訪問 DOM。 例如,如果您想通過 refs 訪問 DOM 元素,這很重要。
useEffect
保證在依賴項沒有改變的情況下它不會被觸發。 useMemo
不提供此類保證。
如React 文檔中所述,您應該將 useMemo 視為純優化技術。 即使您用常規函數調用替換 useMemo,您的程序也應該繼續正常工作。
useEffect
+ useState
可用於控制更新。 甚至打破循環依賴並防止無限更新循環。
我想說除了異步性質之外,它們的設計方式可能存在一些差異。
useEffect
是一個集體調用,無論異步與否,它都是在所有組件渲染后收集的。
useMemo
是一個本地調用,它只與這個組件有關。 您可以將useMemo
視為另一個賦值語句,有時可以跳過賦值語句。
這意味着, useMemo
是更為迫切,然后useLayoutEffect
和最后被useEffect
,特別是當輸入是來自一個道具。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.