[英]Why use useMemo and not useCallback here?
因此,據我了解,兩者之間的區別在於,如果在返回原語時返回 useMemo 時返回 function 或 object 或數組,則使用 useCallback。 但我正在查找去抖動(這是文章: https://dmitripavlutin.com/react-throttle-debounce/它說 useMemo 將是一個更好的解決方案。使用 useCallback
import { useState, useCallback } from 'react';
import debounce from 'lodash.debounce';
export function FilterList({ names }) {
const [query, setQuery] = useState("");
let filteredNames = names;
if (query !== "") {
filteredNames = names.filter((name) => {
return name.toLowerCase().includes(query.toLowerCase());
});
}
const changeHandler = event => {
setQuery(event.target.value);
};
const debouncedChangeHandler = useCallback(
debounce(changeHandler, 300)
, []);
return (
<div>
<input
onChange={debouncedChangeHandler}
type="text"
placeholder="Type a query..."
/>
{filteredNames.map(name => <div key={name}>{name}</div>)}
</div>
);
}
用 useMemo
import { useState, useMemo } from 'react';
import debounce from 'lodash.debounce';
export function FilterList({ names }) {
const [query, setQuery] = useState("");
let filteredNames = names;
if (query !== "") {
filteredNames = names.filter((name) => {
return name.toLowerCase().includes(query.toLowerCase());
});
}
const changeHandler = (event) => {
setQuery(event.target.value);
};
const debouncedChangeHandler = useMemo(
() => debounce(changeHandler, 300)
, []);
return (
<div>
<input
onChange={debouncedChangeHandler}
type="text"
placeholder="Type a query..."
/>
{filteredNames.map(name => <div key={name}>{name}</div>)}
</div>
);
}
我不明白。 debounce 是否返回原始值? 如果不是,我們如何使用 useMemo? 還有這里的 useMemo 比 useCallback 好在哪里?
首先關於你的報價:
如果返回原語時返回 function 或 object 或數組,則使用 useCallback
不,這是錯誤的。 useCallback
主要用於記憶函數。 useMemo
有助於避免在每次渲染時進行昂貴的計算。
現在來看這篇文章。 那篇文章更喜歡useMemo
的另一個原因是性能。 盡管我懷疑在大多數此類情況下性能差異會很明顯。
const debouncedChangeHandler = useCallback(
debounce(changeHandler, 300)
, []);
它說:
然而......這個實現有一個小的性能問題:每次組件重新渲染時, debounce(changeHandler, 300) 創建一個去抖動 function 的新實例。
也就是說,即使debouncedChangeHandler
由於useCallback
在重新渲染中保持不變, debounce debounce(changeHandler, 300)
仍然在每次渲染時執行。
但是使用useMemo
:
const debouncedChangeHandler = useMemo(
() => debounce(changeHandler, 300)
, []);
它聲稱:
useMemo(() => debounce(changeHandler, 300), []) 記憶去抖處理程序,但也僅在組件的初始渲染期間調用 debounce() 。
這就是文章更喜歡useMemo
的原因。
運行此代碼:
let T1 = () => console.log('test1');
let T2 = () => console.log('test2');
export default function App() {
let f = React.useCallback(T1(), []);
let g = React.useMemo(() => T2(), []);
let [x, setX] = React.useState(0);
return (
<div
onClick={() => {
setX(x + 1);
}}
>
<h1>{x}</h1>
<p>Start editing to see some magic happen :)</p>
</div>
);
}
在任意位置單擊div
並查看test2
如何不再記錄。
const debouncedChangeHandler = useCallback(
debounce(changeHandler, 300)
, []);
在每個渲染中:
debounce(changeHandler, 300)
將運行(它不是 function,它是一個被調用函數)並解析為一個值(這是一個回調) const debouncedChangeHandler = useMemo(
() => debounce(changeHandler, 300)
, [])
在每次渲染中
() => debounce(changeHandler, 300)
不會運行,是 value(callback)如果你想返回一個值,使用useMemo如果你使用useMemo,它會產生副作用,讓代碼看起來很糟糕。 如果你想返回一個回調,使用useCallback
關於 useMemo 和 useCallback https://medium.com/@jan.hesters/usecallback-vs-usememo-c23ad1dc60之間差異的精彩文章
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.