2 回答

TA贡献1843条经验 获得超7个赞
lodash debounce 将函数作为第一个参数。您可以简单地用作函数,并在调用时传递给该函数,然后将其传递给fetchDatasearchValuedebounceLoadDatafetchData
const debounceLoadData = useCallback(debounce(fetchData, 1000), []);
useEffect(() => {
debounceLoadData(searchValue);
console.log({searchValue})
}, [searchValue]);
debounce实际上返回一个函数,认为deboounce是像这样实现的
function debounce(func, wait) {
let timeout
return function(...args) {
const context = this
clearTimeout(timeout)
timeout = setTimeout(() => func.apply(context, args), wait)
}
}
所以基本上是这里返回的函数,然后被传递给原始函数 fetchData,就像debounceLoadDataarguments passed to it i.e ...argsfunc.apply(context, args)
也只创建一次,因为回调依赖关系是,你传递它使用Effect作为不依赖关系不会有任何区别。debounceLoadData[]
请阅读这篇文章,了解缺少依赖关系警告

TA贡献2039条经验 获得超7个赞
我从不喜欢,这是一个非常令人困惑的钩子,我总是使用,因为它完全涵盖了可以做的事情(但不是相反)。useCallbackuseMemouseCallback
function SearchBar() {
const [searchValue, setSearchValue] = useState("");
const handleSearchFieldChange = ((value:string) => {
setSearchValue(value);
});
const debounceLoadData = useMemo(() => debounce(fetchData, 1000), []);
/**
* the equivalent of useCallback should be:
*
* const debounceLoadData = useCallback(debounce(fetchData, 1000), []);
*
* But I really advice against it!
* There's unnecessary function invocation compared to useMemo.
*/
useEffect(() => {
debounceLoadData(searchValue); // <- you should pass in arg
console.log({searchValue})
}, [searchValue]);
// ...
}
然而,对于您的情况,我不认为使用lodash debounce是最好的解决方案。
存在一个隐藏的风险,即在卸载组件后,将最终调用 effect。如果包含某些状态突变逻辑,则会引发错误“无法在未挂载的组件上调用 setState(或 forceUpdate)”,这不会造成破坏性,但也不是最佳的。fetchDatafetchData
我建议使用手动去抖动调用。这很简单:setTimeout/clearTimeout
useEffect(() => {
const timeoutId = setTimeout(() => fetchData(searchValue), 1000)
return () => clearTimeout(timeoutId)
}, [searchValue])
添加回答
举报