[Fixed] Why am I getting the previous value of state?

Issue

I am trying to make a service call inside the eventhandler called onChange of the value in select. But inside my event handler, either I am getting the previous value of state or my state is not getting updated.

What could be causing this?

How can I handle this change of state so it gives me the updated value?

This is my Component

function CountryDataAra65(props){

const [countryOption, setCountry] = useState("Select a country");
const [countryData, setCountryData] = useState([]);

var cardBody;

// Tags for table
const PPTag = "Purchasing Power";
const CLTag = "Cost of Living";
const HCTag = "Health Care";
const CRTag = "Crime Index";
const PLTag = "Pollution Index";
const QLTag = "Qualit of Life";

// When a country is selected
// When this event handler is called onChange of select, the state(countryOption) gives me the previous value
async function onCountrySelected(e){
    const val = e.target.value;
    await setCountry(val);

    console.log(countryOption);
    
    // To pass country as object
    const country = {
        "country": countryOption
    }

    // To get country's data
    // This is a service call
    await getCountryData(country)
    .then(data =>{
        setCountryData(data);
        console.log(data);
    })
    .catch(error =>{
        console.log(error);
    })
}

Below is my select input


<select className="form-control" aria-label="Default select example"  onChange={onCountrySelected}>
  <option selected>Select a country</option>
  {
    props.data.map((item, key) => {
      return (
        <option defaultValue={item} key={key}>{item}</option>
      )        
    })
  }
</select>

Solution

React hooks (out of the box) are not async. So calling await setCountry doesn’t do anything. Secondly, if you want the updated value of countryOption inside the onCountrySelected method, you can simply use the value from e.target.value.

function CountryDataAra65(props) {
  const [countryOption, setCountry] = useState("Select a country");
  const [countryData, setCountryData] = useState([]);

  var cardBody;

  // Tags for table
  const PPTag = "Purchasing Power";
  const CLTag = "Cost of Living";
  const HCTag = "Health Care";
  const CRTag = "Crime Index";
  const PLTag = "Pollution Index";
  const QLTag = "Qualit of Life";

  // When a country is selected
  // When this event handler is called onChange of select, the state(countryOption) gives me the previous value
  async function onCountrySelected(e) {
    const val = e.target.value;
    setCountry(val);

    console.log(countryOption);

    // To pass country as object
    const country = {
      country: val,
    };

    // To get country's data
    // This is a service call
    await getCountryData(country)
      .then((data) => {
        setCountryData(data);
        console.log(data);
      })
      .catch((error) => {
        console.log(error);
      });
  }
}

Leave a Reply

(*) Required, Your email will not be published