我正在尝试编写自定义钩子,但是每当我想将函数用作参数时,我都会遇到问题。
我想写一个使用Debouce钩子;从网络上的例子中,我最终得到了这个:
import { useCallback, useEffect } from 'react';
import debounce from 'lodash/debounce';
const useDebounce = (fn, time, options) => {
useEffect(() => console.log('reset'), [fn, time, options]);
return useCallback(debounce(fn, time, options), [fn, time, options]);
};
每当参数更改时,我想重置。
但是,如果我像这样使用它:
const randomComponent = () => {
const doSomething = useDebounce(() => console.log('test'), 500, {maxWait: 1000});
// ...
};
每次我的组件呈现函数和对象引用更改(第一个和第三个参数(时,这意味着我每次都会创建一个新的去抖动函数。 因此,去抖动行为不起作用。
处理每次渲染时更改的回调引用的最佳方法是什么?
没有出路,用户必须确保它具有相同的引用:
import { useCallback, useEffect } from 'react';
import debounce from 'lodash/debounce';
const useDebounce = (fn, time, options) => {
useEffect(() => {
// Don't forget to cancel the debounce
return () => debounce(fn).cancel();
}, [fn, time, options]);
return useCallback(debounce(fn, time, options), [fn, time, options]);
};
const log = () => console.log('test');
const maxWait = { maxWait: 1000 };
// Outer scope holds the same reference
const randomComponent = () => {
const doSomething = useDebounce(log, 500, maxWait);
};
// Or memoization, more usefull with state
const randomComponent = () => {
const log = useCallback(() => console.log('test'), []);
const maxWait = useMemo(() => ({ maxWait: 1000 }), []);
const doSomething = useDebounce(log, 500, maxWait);
};
此外,如果您不想处理引用,用户可能会提供比较功能。可能建议尝试另一种方法:
// Something like that (not tested)
const useDebounce = (fn, time, options, comp) => {
const debounceRef = useRef(debounce(fn, time, options));
if (comp(fn, time, options)) {
debounce(debounceRef.current).cancel();
debounceRef.current = debounce(fn, time, options);
}
return useCallback(debounceRef.current, []);
};