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
.
run
function is invoked, the current ref value is "unpacked".You could fix case 2 by populating the
useMemo
hook's dependency array to re-enclose the current ref value.Example:
BTW, for case 1 you should use an
useEffect
hook to set the ref value when thefn
updates.Example: