1

I have some code similar to this:

const [thing, setThing] = useState('');
const [value, setValue] = useState({
  thing: '',
  somethingElse: '',
});

//...

setThing(aThing);
setValue((prev) => ({ ...prev, thing: aThing }));

later in the code, can I guarantee that thing === value.thing? Or are the two useState setters possibly called at different times?

Anhdevit
  • 1,926
  • 2
  • 16
  • 29
brendangibson
  • 2,377
  • 2
  • 21
  • 36
  • Does this answer your question? [Multiple calls to state updater from useState in component causes multiple re-renders](https://stackoverflow.com/questions/53574614/multiple-calls-to-state-updater-from-usestate-in-component-causes-multiple-re-re) – Anhdevit Oct 14 '20 at 03:09
  • 1
    That is helpful. I think https://github.com/facebook/react/issues/14259 is saying that `thing === value.thing` is not guaranteed to be true if the "set" functions are not batched. – brendangibson Oct 14 '20 at 03:25

1 Answers1

1

The setState is async function and it's possible that the the first setState will finish before the second statement if the update is not batched.

React currently will batch state updates if they're triggered from within a React-based event, like a button click or input change. It will not batch updates if they're triggered outside of a React event handler, like a setTimeout().

setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the updater argument below.

This form of setState() is also asynchronous, and multiple calls during the same cycle may be batched together. For example, if you attempt to increment an item quantity more than once in the same cycle, that will result in the equivalent of:

Object.assign(
  previousState,
  {quantity: state.quantity + 1},
  {quantity: state.quantity + 1},
  ...
)

Subsequent calls will override values from previous calls in the same cycle, so the quantity will only be incremented once. If the next state depends on the current state, we recommend using the updater function form, instead:

this.setState((state) => {
  return {quantity: state.quantity + 1};
});

You can read more for state on React offical doc here.

Sohail Ashraf
  • 10,078
  • 2
  • 26
  • 42