Lets say I have
const [variable, setVariable] = useState(false)
I am trying to do
useEffect(() => {
if (variable==false){
setTimeout(() => {
if (variable==false) {do_something();}
else {do_something_else();}
}, n)
}
}, [variable]);
But the issue is since the inner variable==false
isn’t giving correct results as setVariable
is asynchronous.
Initially variable
is false
. some event is fired which is supposed to set it to true via setVariable(true)
at around 2 sec. So for n<2 sec I am expecting to be false
and n > 2 sec I am expecting it to be true
. right ? Now no matter whatever I set n it never goes into do_something()
. when I an trying to do this way even if I set n = 1 or 0.5 second I am finding it has already become true
from false
.
2
Answers
The value of
variable
inside thesetTimeout
callback will be the value thatvariable
had when thesetTimeout
was set, not the value thatvariable
has when thesetTimeout
callback is executed. This is because JavaScript closures capture the environment in which they are created, which includes thevariable
value at the time thesetTimeout
is called.One way to get the current value of the state inside the
setTimeout
callback is to use a ref to track the latest value. Here is how you can do this:In this code,
variableRef.current
will always hold the latest value ofvariable
. When you update the state by callingsetVariable
, thevariableRef.current
value will be updated in the subsequentuseEffect
call. Then, inside thesetTimeout
callback, you can checkvariableRef.current
to get the latest value.This way, even if
setVariable
is asynchronous, yoursetTimeout
callback will always have access to the latest state value when it is executed.