0

I think this question has kind of been answered before, but I've tried looking through all the similar-titled questions and I'm still a bit confused.

My code requests some data from the what3words API, and then the data is given a variable within an object using setState. However, it is out of sync, so the console.log(modifiedData) shows slug as an empty string. But when you click the submit button again, slug has been updated.

const api = require("@what3words/api");
const [modifiedData, setModifiedData] = useState({
    title: '',
    description: '',
    category: '',
    condition: '',
    capacity: 0,
    slug: '',
    lng: 0,
    lat: 0,
  });
  
const handleSubmit = async e => {
   e.preventDefault();
   api.convertTo3wa({lat: modifiedData.lat, lng: modifiedData.lng}, 'en')
   .then(function(getSlug) {
      setModifiedData((prev) => ({
        ...prev,
        slug: getSlug.words,
      }));
      console.log(modifiedData);
    });
edapm
  • 45
  • 1
  • 9

3 Answers3

1

This is because setState has asynchronous behaviour, so you can't guarantee the data has been updated when you make the console.log.

You have to wait for the component to reRender to ensure your data is there.

const [state, setState = useState(..)
const submitHandler = (e) =>{

setState({... some data})

console.log(state) //data is not gaurenteed
}

console.log(state) // first time : {} 
                   //second time is the data
return(
<div>
<p>app content </p>
</div>
)
}
Kristoffer Tølbøll
  • 3,157
  • 5
  • 34
  • 69
1

Much like setState in Class components created by extending React.Component or React.PureComponent, the state update using the updater provided by useState hook is also asynchronous, and will not be reflected immediately.

Look at this satck overflow question

BeK
  • 171
  • 1
  • 7
0

It's like Ating said. If you want to see the change with console.log you can wrap it with setTimeOut:

const api = require("@what3words/api");
const [modifiedData, setModifiedData] = useState({
   title: '',
   description: '',
category: '',
condition: '',
capacity: 0,
slug: '',
lng: 0,
lat: 0,
  });
const handleSubmit = async e => {
  e.preventDefault();
  api.convertTo3wa({lat: modifiedData.lat, lng: 
  modifiedData.lng}, 'en')
  .then(function(getSlug) {
  setModifiedData((prev) => ({
    ...prev,
    slug: getSlug.words,
  }));
  setTimeOut(()=>{
   console.log(modifiedData);
  },500)      
});
JsHitachi
  • 69
  • 3
  • 8