簡體   English   中英

useMemo 與 useEffect + useState

[英]useMemo vs. useEffect + useState

使用useMemo (例如用於密集函數調用)而不是使用useEffectuseState的組合有useEffect useState

這里有兩個自定義鈎子,乍一看完全相同,除了useMemo的返回值在第一次渲染時為null

在 CodeSandbox 上查看

useEffect & useState

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的記憶在哪里開始?

useEffectsetState將在每次更改時導致額外的渲染:第一個渲染將“滯后”與陳舊數據,然后它將立即使用新數據排隊附加渲染。


假設我們有:

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

我認為在它們之間進行選擇時,您應該考慮兩個要點。

  1. 函數調用的時間。

useEffect在組件渲染后調用,因此您可以從中訪問 DOM。 例如,如果您想通過 refs 訪問 DOM 元素,這很重要。

  1. 語義保證。

useEffect保證在依賴項沒有改變的情況下它不會被觸發。 useMemo不提供此類保證。

React 文檔中所述,您應該將 useMemo 視為純優化技術。 即使您用常規函數調用替換 useMemo,您的程序也應該繼續正常工作。

useEffect + useState可用於控制更新。 甚至打破循環依賴並防止無限更新循環。

我想說除了異步性質之外,它們的設計方式可能存在一些差異。

useEffect是一個集體調用,無論異步與否,它都是在所有組件渲染后收集的。

useMemo是一個本地調用,它只與這個組件有關。 您可以將useMemo視為另一個賦值語句,有時可以跳過賦值語句。

這意味着, useMemo是更為迫切,然后useLayoutEffect和最后被useEffect ,特別是當輸入是來自一個道具。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM