[英]Why use useMemo and not useCallback here?
So as i understand the difference between the two is that useCallback is used if a function or object or array is returned while useMemo when a primitive is returned.因此,据我了解,两者之间的区别在于,如果在返回原语时返回 useMemo 时返回 function 或 object 或数组,则使用 useCallback。 But i was looking up debouncing (this is the article: https://dmitripavlutin.com/react-throttle-debounce/ and it said useMemo would be a better solution. With 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>
);
}
With useMemo用 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>
);
}
And i don't understand.我不明白。 Is debounce returning a primitive value?
debounce 是否返回原始值? If not how can we use useMemo?
如果不是,我们如何使用 useMemo? Also how is useMemo better than useCallback here?
还有这里的 useMemo 比 useCallback 好在哪里?
First about your quote:首先关于你的报价:
useCallback is used if a function or object or array is returned while useMemo when a primitive is returned
如果返回原语时返回 function 或 object 或数组,则使用 useCallback
No, this is wrong.不,这是错误的。
useCallback
is mainly for memoizing functions. useCallback
主要用于记忆函数。 useMemo
helps to avoid expensive calculations on every render. useMemo
有助于避免在每次渲染时进行昂贵的计算。
Now for the article.现在来看这篇文章。 That article prefers
useMemo
for a different reason, that of performance;那篇文章更喜欢
useMemo
的另一个原因是性能。 although I doubt in most such cases the performance difference will be noticeable.尽管我怀疑在大多数此类情况下性能差异会很明显。
const debouncedChangeHandler = useCallback(
debounce(changeHandler, 300)
, []);
It says:它说:
However... this implementation has a small performance issue: each time the component re-renders, a new instance of the debounced function is created by the debounce(changeHandler, 300) .
然而......这个实现有一个小的性能问题:每次组件重新渲染时, debounce(changeHandler, 300) 创建一个去抖动 function 的新实例。
It is saying that even though the debouncedChangeHandler
remains the same across re renders due to useCallback
, the debounce(changeHandler, 300)
is still executed on each render.也就是说,即使
debouncedChangeHandler
由于useCallback
在重新渲染中保持不变, debounce debounce(changeHandler, 300)
仍然在每次渲染时执行。
But with useMemo
:但是使用
useMemo
:
const debouncedChangeHandler = useMemo(
() => debounce(changeHandler, 300)
, []);
it claims:它声称:
useMemo(() => debounce(changeHandler, 300), []) memoizes the debounced handler, but also calls debounce() only during initial rendering of the component.
useMemo(() => debounce(changeHandler, 300), []) 记忆去抖处理程序,但也仅在组件的初始渲染期间调用 debounce() 。
That is the reason why the article prefers useMemo
.这就是文章更喜欢
useMemo
的原因。
Run this code:运行此代码:
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>
);
}
Click div
anywhere and see how test2
isn't logged anymore.在任意位置单击
div
并查看test2
如何不再记录。
const debouncedChangeHandler = useCallback(
debounce(changeHandler, 300)
, []);
in every render:在每个渲染中:
debounce(changeHandler, 300)
will run(it is not a function, it is a called function) and resolve into a value(which is a callback) debounce(changeHandler, 300)
将运行(它不是 function,它是一个被调用函数)并解析为一个值(这是一个回调) const debouncedChangeHandler = useMemo(
() => debounce(changeHandler, 300)
, [])
in every render在每次渲染中
() => debounce(changeHandler, 300)
will not run, it is value(callback) () => debounce(changeHandler, 300)
不会运行,是 value(callback) if you want to return a value, use useMemo if you use useMemo, it will cause side effect, which makes code look bad.如果你想返回一个值,使用useMemo如果你使用useMemo,它会产生副作用,让代码看起来很糟糕。 if you want to return a callback,use useCallback
如果你想返回一个回调,使用useCallback
A great article on differnce between useMemo and useCallback https://medium.com/@jan.hesters/usecallback-vs-usememo-c23ad1dc60关于 useMemo 和 useCallback https://medium.com/@jan.hesters/usecallback-vs-usememo-c23ad1dc60之间差异的精彩文章
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.