const test1 = useCallback(
_.debounce(async (val) => {
console.log("call test");
console.log(value);
console.log(val);
}, 200),[]);
// const test2 = useCallback(
// _.debounce(async () => {
// console.log("call test");
// console.log(value);
// }, 200),
// []
// );
useEffect(() => {
test1(value);
// test2();
}, [value]);
value
is a state variable, whenever it changes, useEffect is called, which calls testX
. Everything looks fine if value
is passed as a parameter in the function, but if value
is used as 'global' variable directly in function, console.log doesn't seem to log the current value of value
even though the state has been changed and should be detected by useEffect().
Example console.log in test1
when type in '12' in regular speed
call test
from State: ""
from Parameter: 12
Am I missing something here? I'm new to React maybe you could recommend some resources to learn about this behaviour?
code sample
CodePudding user response:
const test1 = useCallback(
// ...
,[]);
The empty array says that this function should be created just once, and then never again. Since it's created on the first render, it closes over the variables from that first render, and at that time, value
was ""
.
If you want a new function to be created when value
changes, then either change the useCallback's dependency array to include value
:
const test1 = useCallback(
// ...
,[value]);
Or move the creation of the function into your use effect:
useEffect(() => {
const test1 = _.debounce(async (val) => {
console.log("call test");
console.log(value);
console.log(val);
})
test1(value);
}, [value]);
However, both of these solutions to address the closure variable will break the debouncing behavior, so they are probably not useful to you. Since you can pass the value in, perhaps just stick with that.