[英]Is this incorrect use of useCallback and useMemo?
我們什么時候應該擔心函數組件重新定義變量和函數?
我認為第一種情況顯然是不必要的,創建函數並不昂貴(並且反應開發工具配置文件測試沒有檢測到 useCallback 的性能變化)
import React, { useState, useMemo, useCallback } from "react";
export const App = () => {
const [counter, setCounter] = useState(1);
const showCounter = useCallback(() => {
console.log(counter);
}, [counter]);
return (
<>
<button onClick={showCounter}>Show</button>
<button onClick={() => setCounter(counter + 1)}>Add</button>
</>
);
};
另一方面,在另一個示例中,使用 react 開發工具,我們可以檢測到 useMemo 將渲染時間縮短了一半:
import React, { useState, useMemo, useCallback } from "react";
export const App = () => {
const [counter, setCounter] = useState(1);
const [list, setList] = useState<number[]>([]);
function setListItem(item: number) {
setList([...list, item]);
}
//should we useMemo here?
const domList = useMemo(
() =>
list.map((value: number, index: number) => (
<li key={index}> {value} </li>
)),
[list]
);
return (
<>
<p>{counter}</p>
<button onClick={() => setCounter(counter - 1)}>Subtract</button>
<button onClick={() => setCounter(counter + 1)}>Add</button>
<button onClick={() => setListItem(counter)}>Push to array</button>
<h1>List</h1>
<ul>{domList}</ul>
</>
);
};
但是當我們談論前端時,仍然不到一毫秒的增益和數組映射和 JSX 數組也不是很昂貴的東西。 但是,在每個渲染中運行一個數組 map 方法是很不舒服的。 那么,這些事情我們應該怎么做呢? (讓我們忘記什么時候我們有 useEffect 依賴於一些使 useMemo 成為必要的變量)
您獲得的性能是不同的。 是的,對於useMemo
如果您正在記憶的計算很昂貴,它提供了明顯的直接好處。 但是,對於useCallback
和useMemo
,長期的好處是避免了子組件中不必要的渲染,而不是重新計算的成本。
請記住,如果組件中的任何道具發生變化,它們可能會觸發渲染調用,並且在組件樹中越靠前,它對性能的影響就越大。 這就是我們通常使用這些鈎子的原因。
一般來說,組件有幾個 state 元素,通過備忘錄掛鈎,我們可以建立依賴關系以避免計算冗余。 例如,在您的合成案例中,您有兩個 state 元素: counter
和list
。 每次counter
更改時,您都會通過使其僅依賴於list
來防止重新計算domList
。 如果這是一個葉節點,那么肯定沒有性能提升,但是,這是組件樹的根,如果沒有這些鈎子,性能將不會隨着您添加更多 state 元素而擴展,您將不得不重構代碼以解決性能問題。 當然,如果列表包含超過 1000 個元素, <ul>{domList}</ul>
的成本可能會很高,但<ul><ExpensiveCutie domList={domList} /></ul>
可能需要數周時間才能注意到、調試、和重構。
簡而言之,我建議在容器組件中使用備忘錄掛鈎,而不是在葉組件中。 然而,如果你的葉子組件在你實現它的時候變成了一個容器呢?
在你 go 之前,你甚至需要使用 memo() 嗎? 在這里閱讀更多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.