简体   繁体   中英

react set initial state with async/await variable

I'm using async/await in Javascript to fetch the user's coordinates based on their ip address. I then use those coordinates as the initial state values of a few React components. The call fetch call works, but it is not being awaited. I guess I have something wrong with my use of async/await. How can I make sure that the fetch call returns before proceding? Here is my code:

let ip_address_coords
const get_ip_coords = () => {
  try {
    let resp = fetch("https://ip-geolocation.whoisxmlapi.com/api/v1?apiKey=<my_api_key>")
    let data = resp.json()
    return {lng: data.location.lng, lat: data.location.lat}
  } catch (err) {
    console.log(err)
  }
}

(async () => {
  ip_address_coords = await get_ip_coords();
})()

class Application extends React.Component {
  constructor(props) {
    super()
    this.state = {
      lng: ip_address_coords['lng'],
      lat: ip_address_coords['lat']
    }
    ...

Problem as my point of view you are using async outer function you have to handle it child function i think.

Use like this because every function have their own context so you have to handle that function individually so you can handle async task it two ways: Use async wait on following method Better way of handling use Promiss on inner function then your async wait may work

const get_ip_coords = async () => {
try{
let resp = await fetch("https://ip-geolocation.whoisxmlapi.com/api/v1?apiKey=<my_api_key>")
let data = resp.json()
   return {lng: data.location.lng, lat: data.location.lat}
 } catch (err) {
    console.log(err)
  }
}

OR

 const get_ip_coords = () => {
    return new Promiss((resolve,reject)=>{
             fetch("https://ip-geolocation.whoisxmlapi.com/api/v1?apiKey= 
               <my_api_key>").then(res=>{
                    let data = resp.json()
                    resolve({lng: data.location.lng, lat: data.location.lat})
                }).catch(err=>{
                      reject(err)
                })
    })
}

You can also use callback mechanism also.

I'm still not sure why this didn't work as originally written, but the solution I found was to make the componentDidMount method of the component that actually uses the coordinates async.

It looks like this:

  get_ip_coords = () => {
    return new Promise(async (resolve, reject) => {
      const resp = await fetch("https://ip-geolocation.whoisxmlapi.com/api/v1?apiKey=<my_api_key>")
      const data = await resp.json()
      resolve([data.location.lng, data.location.lat])
    })
  }
  
  componentDidMount = async () => {
    const map = new mapboxgl.Map({
      center: await this.get_ip_coords(),
      ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM