-3

function LoginComponent(){
  const [clicked, setClicked] = useState(false)
  
  function handleClick(){
    console.log('before', clicked)
    setClicked(true)
    console.log('after', clicked)
  }
  return(
    <a onClick={handleClick}>
      random text
      </a>
  )
}

When I run this, the console outputs before false after false. Why is this? I have no clue why this behavior is like this.

Anon Eemus
  • 15
  • 1
  • 3
  • 1
    State is updated asynchronously and it is constant within a particular render of a component. Component can't see the updated state until it re-renders. You can use the `useEffect` hook to see the updated state: `useEffect(() => { console.log(clicked) }, [clicked])` – Yousaf Oct 20 '21 at 12:01
  • `clicked` is assigned in the line `const [clicked, setClicked] = useState(false)` **only**. Calling `setState` will update the internal state, resulting in the _next_ call to `useState` to return the new value, but it cannot automagically change your local variable `clicked` too. (You could instead write something like `setClicked(clicked = true)` and change `const` to `let` so that `clicked` is changeable.) – CherryDT Oct 20 '21 at 12:02
  • Does this answer your question? [setState doesn't update the state immediately](https://stackoverflow.com/questions/41278385/setstate-doesnt-update-the-state-immediately) – Sinan Yaman Oct 20 '21 at 12:05

3 Answers3

1

Because setting state is an asynchronous action. It takes some time to update. Check react documentation link to know more

You can check the updated value by

    useEffect(()=> { 
         console.log("clicked", clicked);
 },[clicked]);
Ram Rana
  • 194
  • 6
1

There are couple of reasons for this behavior:

  • State is updated asynchronously
  • In any particular render, state and props don't change, changes are only reflected when component re-renders

If you want to log the updated value of clicked, put the log statement in the useEffect hook.

You can't update and log the updated value of any state variable in the same render. Component will have to re-render to reflect changes due to state update.

Similarly, if you want to call a function with the updated value of clicked, call the function from inside the useEffect hook.

Ferin Patel
  • 3,424
  • 2
  • 17
  • 49
1

setClicked is asynchronous. You must check the state updated in useEffect

function LoginComponent(){
  const [clicked, setClicked] = useState(false)
  
  function handleClick(){
    setClicked(true)
  }

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

  return(
    <a onClick={handleClick}>
      random text
      </a>
  )
}
Vitaliy Rayets
  • 2,299
  • 1
  • 6
  • 12