Vigneshwar M
Vigneshwar M

Reputation: 113

changing multiple states in react js useState() hook

So I was wondering what actually happens when I change more than one state in a handler function. Will they both get updated simultaneously or they will be executed one after another.

const [x, setX] = useState(0)
const [y, setY] = useState(0)

const handlerFunction = () => {
  setX(x+1)
  setY(y+1)
}

Also what If one state depend on others?

const handlerFunction = () => {
  setX(x+1)
  setY(x+1)
}

or what if

const [x, setX] = useState(0)
const [y, setY] = useState(x)

const handlerFunction = () => {
  setX(x+1)
  setY(y+1)
}

Upvotes: 1

Views: 3867

Answers (3)

Olivier Boissé
Olivier Boissé

Reputation: 18083

https://github.com/facebook/react/issues/14259

React batches state updates if they're triggered from within a React-based event

So if you call the handler from a onClick, onChange, onBlur... React will apply the multiple updates simultaneously. If you call the handler from a Promise or a setTimeout, the updates will be called separately.

If a state variable depends of another, I suggest to group them into an object like below :

const [obj, setObj] = useState(() => ({x: 0, y: 0}));

const handlerFunction = () => {
  setObj(prevObj => {
    const newVal = prevObj.x + 1;
    return {x: newVal, y: newVal};
  });
};

Upvotes: 2

Patrick Roberts
Patrick Roberts

Reputation: 51766

Nothing ever runs simultaneously in JavaScript*, so the state updates occur one after the other. But since they're both done asynchronously, you won't see x or y update until the next render, so it will appear simultaneous from your perspective.

So in all three cases above, the final values for x and y after calling handlerFunction() once will be 1 and 1.

Also note that because x and y are simply variables, their values can't change synchronously anyway, which is why you only see their values update in the next render.

Just so you're aware though, it's good practice to use functional updates when your state changes rely on the previous state:

const handlerFunction = () => {
  setX(x => x + 1)
  setY(y => y + 1)
}

This ensures that each update is an atomic operation.

*Unless you're dealing with worker threads

Upvotes: 3

Atin Singh
Atin Singh

Reputation: 3690

Setting a state is asynchronous in nature so -

const handlerFunction = () => {
  setX(x+1)
  setY(x+1) // here the old value of x will be taken and the outcome value of x and y     will be different //                   
}

Here -

const [x, setX] = useState(0)
const [y, setY] = useState(x) // this is just to initialize an initial value to your state y so it will be once set to the value of x and then it doesn't depends on x//

const handlerFunction = () => {
  setX(x+1)
  setY(y+1)
}

Upvotes: 0

Related Questions