我正在尝试编写自定义钩子,但是每当我想将函数用作参数时,我都会遇到一个问题。
我想写一个useDebouce钩子;从网络上的示例中,我得出以下结论:
async (ctx, next) => {
ctx.set('Set-Cookie','name=fromBackEnd;max-age=303003030;Domain=http://localhost:8080;path=/');
ctx.response.type = 'application/json';
ctx.response.body = await query.menu({where: {...tool.parseUrl(ctx.request.url), flag: 0}})
}
无论何时更改参数,我都想重置。
但是,如果我这样使用它:
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]);
};
每次我的组件呈现函数和对象引用更改(第一个和第三个参数)时,这意味着我最终每次都会创建一个新的去抖动的函数。 因此,防抖行为不起作用。
处理每次渲染时更改的回调引用的最佳方法是什么?
答案 0 :(得分:1)
没有出路,用户必须确保它具有相同的引用:
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, []);
};