Just to give a bit more explanation:
The value returned by useState is stored as a regular variable. When you create an instance of myFunction
, it gets tied to the closure of that specific render, and to that specific value
variable.
For your case, where you call setValue
and then need to do something with that value, PhantomSpooks' answer is spot on: either use a local variable to store and distribute the updated value, or move that logic to useEffect
(usual useEffect caveats apply in that case; it may be asynchronous and may be executed multiple times).
The generic way to circumvent this limitation of useState
is to use a ref, as Chari proposes, though not as written in the answer; you should replace state with ref, as setting the ref won't trigger re-render.
You may use a ref as secondary storage, like that:
const [value, setValue] = useState(1);
// This sets only initial value for the ref. You have to be mindful of setting it explicitly when calling seValue.
const liveValue = useRef(value);
// A tempting option might be to just add a line
liveValue.current = value;
// but this is quite risky and may lead to subtle bugs,
// as the ref won't be updated immediately on setValue, leading to
// possible race conditions.
function myFunction1() {
// Better to update it manually
setValue(newValue);
liveValue.current = newValue;
}
function myFunction2() {
// This will always use the last set value of liveValue.current.
doSomething(liveValue.current);
}
As you can see, useRef
can be tricky, so it's usually best to stick to the previous solution, either the local variable or useEffect
, depending od the semantics of what you are doing.