5

Why doesn't the state change on first click?

const [building, setBuilding] = useState(0);
<Button 
     title="tester"
          onPress={() => {
            setBuilding(1);
            console.log(Building);
          }}/>

The console log always returns "0" on first click, instead of expected "1". How do I fix this?

lache
  • 608
  • 2
  • 12
  • 29
  • 4
    State updates are asynchronous. – Dave Newton Apr 16 '21 at 17:11
  • 1
    like Dave Newton said, the state update won't be immediately reflected within the on Press function. If you want to see state updating console log inside of a useEffect – Rob Terrell Apr 16 '21 at 17:12
  • Also, see [this](https://github.com/facebook/react/issues/11527#issuecomment-360199710), [this](https://reactjs.org/docs/react-component.html#setstate), [this](https://stackoverflow.com/q/41446560/2873538), [this](https://stackoverflow.com/q/54069253/2873538), [this](https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous). – Ajeet Shah Apr 16 '21 at 17:14
  • that answers the question thank you. Does one normally close questions or leave them up for others? I feel my question is far easier to understand than the links it shows me. – lache Apr 16 '21 at 17:53

1 Answers1

13

as state updates are async, you may see your state value updating by adding building to a useEffect dependency, thus causing it to fire whenever the value of building changes.

const [building, setBuilding] = useState(0);

  useEffect(() => {
    console.log(building);
  }, [building]);

  return (
    <button
      title="tester"
      onClick={() => {
        setBuilding(1);
      }}
    >
      test
    </button>
  );
Rob Terrell
  • 2,398
  • 1
  • 14
  • 36
  • 1
    I see. Then technically I need to setBuilding(1) inside the useEffect to "actually" change it. Is that right? – lache Apr 16 '21 at 17:56
  • I only ask because the goal is to actually change it on first click not just see the console log change. depending on where i put it. Would your solution change Building on first click? – lache Apr 16 '21 at 17:57
  • no, the on click handler does the state update. the only reason it is not readily available in your on press function is due to the fact that setting state is async. if you are displaying building value in jsx you will see its value update correctly. The only reason for the useEffect is if you needed to do something to the building value before rendering it – Rob Terrell Apr 16 '21 at 18:00
  • 1
    attached is a code sandbox to show you what I mean https://codesandbox.io/s/mystifying-wind-qt18k?file=/src/App.js:0-388 – Rob Terrell Apr 16 '21 at 18:03
  • so in lamens terms, the useEffect will just get the "0" out of the way on load so when I click it the button the first time it does show the correct number. – lache Apr 16 '21 at 18:17
  • if you're using an onClick to update the state the useEffect isn't necessary, unless you want to do something extra to building. – Rob Terrell Apr 16 '21 at 18:22