Is useState synchronous?

JavascriptReactjsReact Hooks

Javascript Problem Overview


In the past, we've been explicitly warned that calling setState({myProperty}) is asynchronous, and the value of this.state.myProperty is not valid until the callback, or until the next render() method.

With useState, how do I get the value of the state after explicitly updating it?

How does this work with hooks? As far as I can tell, the setter function of useState doesn't take a callback, e.g.

const [value, setValue] = useState(0);
setValue(42, () => console.log('hi callback');

doesn't result in the callback being run.

My other workaround in the old world is to hang an instance variable (e.g. this.otherProperty = 42) on the class, but that doesn't work here, as there is no function instance to reuse (no this in strict mode).

Javascript Solutions


Solution 1 - Javascript

You can use useEffect to access the latest state after updating it. If you have multiple state hooks and would like to track the update on only part of them, you can pass in the state in an array as the second argument of the useEffect function:

useEffect(() => { console.log(state1, state2)}, [state1])

The above useEffect will only be called when state1 is updated and you shouldn't trust the state2 value from inside this function as it may not be the latest.

If you are curious about whether the update function created by useState is synchronous, i.e. if React batches the state update when using hooks, this answer provide some insight into it.

Solution 2 - Javascript

Well, if you refer to the relevant docs you'll find...

const [state, setState] = useState(initialState);

>Returns a stateful value, and a function to update it.

>During the initial render, the returned state (state) is the same as the value passed as the first argument (initialState).

>The setState function is used to update the state. It accepts a new state value and enqueues a re-render of the component.

setState(newState);

>During subsequent re-renders, the first value returned by useState will always be the most recent state after applying updates.

So your new state, whatever it is, is what you've just set in useState, i.e. the value of initialState. It goes directly to state, which updates reactively thereafter. Quoting further from the relevant docs:

>What does calling useState do? It declares a “state variable”. Our variable is called count but we could call it anything else, like banana. This is a way to “preserve” some values between the function calls — useState is a new way to use the exact same capabilities that this.state provides in a class. Normally, variables “disappear” when the function exits but state variables are preserved by React.

If you'd like to do something whenever your state updates, then just use componentDidUpdate.(docs)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnilRedshiftView Question on Stackoverflow
Solution 1 - JavascriptClaire LinView Answer on Stackoverflow
Solution 2 - JavascriptbenasView Answer on Stackoverflow