-1

I don't quite understand how React toggles booleans. So, I've got two buttons. One console.logs current value of the state(which is set to true) and the other one updates it to opposite(false) and console.logs its value. Problem is that according to console.log of second button state isn't changing, but when I check the state with first button it shows that state was updated.

const App = () => {
const[toggle, setToggle] = useState(true);
return(
        
<button onClick={()=>{
            console.log(toggle)
          }}>Button 1</button>
          
<button onClick={()=>{
            setToggle(!toggle)
            console.log(toggle)
          }}>Button 2</button>
}
tomgru23
  • 109
  • 5
  • 1
    Sometimes there's a lag between state updating and the react component knowing it's updated. Try logging toggle outside of the function that is setting state. – displacedtexan Nov 12 '20 at 22:23
  • 1
    `setToggle` doesn't instantly change the value of the `toggle` variable - that would be impossible. Instead it schedules a rerender with the new value. So your `console.log` runs "too early" to "see" the change. – Robin Zigmond Nov 12 '20 at 22:25
  • 1
    `setState` is asynchronous, whenever you click the button the state changes, but it won't show if you immediately try to log it. – Countour-Integral Nov 12 '20 at 22:27
  • 1
    Also related: [setState doesn't update the state immediately](https://stackoverflow.com/questions/41278385/setstate-doesnt-update-the-state-immediately/41278440) and [State Updates May Be Asynchronous (React docs)](https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous) – Henry Woody Nov 12 '20 at 22:27

1 Answers1

1

useState() is asynchronous, so state doesn't update immediately after being called.

Use the function useEffect() to check state. Add the following line to your App:

useEffect(() => console.log('UseEffect says:',toggle));

Also, import useEffect:

import React, {useState, useEffect} from 'react';

So in sum try this:

import './App.css';
import React, {useState, useEffect} from 'react';
import SearchPhotos from './SearchPhotos';

const App = () => {
  const[toggle, setToggle] = useState(true);
  
  useEffect(() => console.log('UseEffect says:',toggle));

  return(
    <>
    <button onClick={()=>{
                console.log('button1',toggle)
              }}>Button 1</button>
              
    <button onClick={()=>{
                setToggle(!toggle)
                console.log('button2',toggle)
              }}>Button 2</button>
    </>
  )
}

export default App;

You can see that in the console, useEffect() displays correct value. Reference: console log the state after using useState doesn't return the current value

Omar Shishani
  • 379
  • 3
  • 8