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

function Test() {
    
    const [addtolist, Setaddtolist] = useState();      
    
    const Onclick = () =>{
        Setaddtolist('Button Clicked');
       
        //I need the state in this function
        console.log(addtolist)
    }

    // I can't console.log(addtolist) here
    

      return (
       <div>
        <button onClick={() => Onclick()}>Test Button</button>
       </div>
      );
    }
    
    export default Test;
    

Why wont the addtolist state update on the first click? It will fire second time, but not first why(undefined)?

bacco2
  • 300
  • 2
  • 9
  • This happens because the set command is running asynchronous to your code. "addtolist" will not be updated immediately. – Vlad Mar 30 '21 at 17:41
  • 3
    As @Vlad told you, `setState` is an asynchronous action so what you are displaying is the first state of **addtolist** that is `null | undefined`. If you want to actually see the current state you setted then use **useEffect** hook: `useEffect(() => { console.log(addtolist); }, [addtolist])` – Ezequiel S. Sandoval Mar 30 '21 at 17:44
  • Here is a good explanation of what is happening and options : https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately – Vlad Mar 30 '21 at 17:55

2 Answers2

1

setState is an asynchronous action so what you are displaying is the first state of addtolist that is either null | undefined. If you want to actually see the current state you setted then use useEffect hook: useEffect(() => { console.log(addtolist); }, [addtolist])

0

I see an issue here with the function you are passing to onClick. When you call this function:

 const Onclick = () =>{
        Setaddtolist('Button Clicked');
       
        //I need the state in this function
        console.log(addtolist)
    }

It will call everything you have between curly bracets. But then, you have put this onClick handler into another function:

onClick={() => Onclick()}

And this is causing the strange behaviour, because when this is called, it will return an onClick handler function you defined higher. It will not be called, just returned.

To fix this, I would simply define the button like this:

const Onclick = () =>{
        Setaddtolist('Button Clicked');
       
        //I need the state in this function
        console.log(addtolist)
        }

   return(
    <div>
        <button onClick={onClick}>Test Button</button>
    </div>);

It passes the whole function as it is to the onClick parameter, it will then be called when the button is clicked. No need to wrap it anymore.

Diceros
  • 83
  • 6
  • There's no difference between these two in terms of the question being asked. I agree there's no point in adding an extra function there, but it doesn't solve the question. – Zachary Haber Apr 01 '21 at 16:56