This is my own hook which is used to realize debounce in React Hooks
import { useMemo, useRef } from "react";
import { debounce } from "lodash";
export function useDebounceFn(fn, wait) {
const fnRef = useRef(fn)
fnRef.current = () => {
debugger
fn()
}
const debounceFn = useMemo(() => {
// Case One: can get the newest fn everytime
return debounce(() => {
fnRef.current()
});
// Case Two: only can get the first fn
return debounce(fnRef.current);
}, []);
return {
run: debounceFn,
cancel: debounceFn.cancel,
}
}
I think debounce(fnRef.current) is equal to debounce(() => { fnRef.current() }) ,but the truth is that they are different and i wonder why. Is there any wrong with my code or just useMemo do something different in these two cases.
const { run } = useDebounceFn(() => {
console.log("num", num);
});
useEffect(() => {
run();
}, [num]);
When i use case one, i can get the newest num and this is what i want to realize, but when i use case two, everytime run function only can get the inital num. i want to know why the case two only can get the inital value, in others word, why the case one can always get the newest value in useMemo.
runfunction is invoked, the current ref value is "unpacked".You could fix case 2 by populating the
useMemohook's dependency array to re-enclose the current ref value.Example:
BTW, for case 1 you should use an
useEffecthook to set the ref value when thefnupdates.Example: