sara lance
sara lance

Reputation: 603

Change the state based on the previous state with React Hooks

I was watching a tutorial and in one moment he does this:

export default function Editor(props) {
  const [open, setOpen] = useState(true);

  return (
    <div className={`container ${open ? "" : "collapsed"}`}>
       <button onClick={() => setOpen((prevOpen) => !prevOpen)}>O/C</button>
    </div>
  );
}

My question is: why this

<button onClick={() => setOpen((prevOpen) => !prevOpen)}>O/C</button>

and not

<button onClick={() => setOpen(!open)}>O/C</button>

I tried both and they seem to work.

Upvotes: 3

Views: 7817

Answers (2)

Nicholas Tower
Nicholas Tower

Reputation: 84902

Because open may not actually be the previous state. In your code it is, but in more complicated components there may be multiple pieces of code that set state. If these happen at around the same time, react may batch them up and apply them all at once.

Usually, these pieces of code will be in separate parts of the component and thus it's hard to spot. But for demonstration purposes, i'll put them right next to eachother:

onClick={() => {
  setOpen(!open)
  setOpen(!open)
})

With the above code, we ask react to set the state to false, and then we ask react to set the state to false again. End result is that it's false. That's probably not what's intended: if we toggle the state twice, it's probably because we want it to go back to the original state.

onClick={() => {
  setOpen((prevOpen) => !prevOpen)
  setOpen((prevOpen) => !prevOpen)
})

This code will set it to false, and then set it to true. Each function gets passed in the most recent value, even if that value is different than the value of open in the closure.

Upvotes: 8

user14355672
user14355672

Reputation:

When you want to update the state which depends on the previous state then you need to call the setState like <button onClick={() => setOpen((prevOpen) => !prevOpen)}>O/C</button>. This is the important rule of how you set the state.

Upvotes: 0

Related Questions