【问题标题】:Question About Which Order React Components Run In Relation To Async Functions关于与异步函数相关的 React 组件运行顺序的问题
【发布时间】:2021-02-09 01:39:18
【问题描述】:

我有一个应用程序,当用户加载它时,它使用 Javascript 的内置 API 来获取地理位置数据。然后,它将这些数据传递给一个组件,该组件应该在对 OpenWeather 的 API 调用中使用它。但是,API 调用发生在 Geolocation 加载之前。我尝试让我的 useLocation 函数异步等待(成功),但它不起作用。

这是我的 App.js

的代码
 const useLocation = () => {
  const [location, setLocation] = useState({lat: 0, long: 0})

    useEffect(()=>{
      const success = (position) =>{ 
        let lat = position.coords.latitude
        let long = position.coords.longitude
   
        
        console.log(lat, long)
        setLocation({lat: lat, long: long})
        
      }
       navigator.geolocation.getCurrentPosition(success)

    },[])

    return location;

}


function App() {
  // Gets just the
 const location = useLocation()

function App() {
  // Gets just the
 const location = useLocation()
    
  const routes = ['nasa','openweather','zomato']

  return ( 
    <div className="App"> 

 

      <Route exact path="/openweather">
        <Weather position={location} />
      </Route>

</div>

}

这是 Weather.js

的代码
import { useState, useEffect } from "react"

const Weather = ({ position }) => {

    const long = position.long
    const lati = position.lat

    const APIKey = '1234'

    const [weather, setWeather] = useState()

    const initData = async () => {
        const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${lati}&lon=${long}&appid=${APIKey}`)
        
        const weatherData = await response.json()
            setWeather(weatherData)


        console.log(response)
    }

    useEffect(()=> {
        initData()
    },[])

【问题讨论】:

  • 您需要检查是否加载了if (long &amp;&amp; lat) { initData() }的地理位置数据。您可能还需要一个比零更好的标记值,因为零是一个完全合理的纬度或经度值。请参阅我对您上一个问题的答案的评论。
  • 不,我的问题不是返回调用,而是函数运行的顺序。地理位置的加载时间比 api 调用要长。

标签: javascript reactjs async-await react-hooks react-state


【解决方案1】:

Geolocation getCurrentPosition 在异步函数回调 success 上获取结果

const success = (position) => { 
  const lat = position.coords.latitude
  const long = position.coords.longitude

  console.log(lat, long)
}

navigator.geolocation.getCurrentPosition(success)
console.log('I will log before geolocation gets position')

为了使其同步,我们需要将它们包装在一个 Promise 中,并将解析放在 success 回调函数中。

const geolocationGetCurrentPosition = () => {
  return new Promise((resolve, reject) => {
    const success = (position) => {
      const lat = position.coords.latitude;
      const long = position.coords.longitude;

      resolve({ lat, long });
    };
    const error = (err) => {
      reject(err);
    };
    navigator.geolocation.getCurrentPosition(success, error);
  });
};

const run = async () => {
  await geolocationGetCurrentPosition()
  console.log("I'm synchronous, I will log after geolocation gets position")
}

这是结果代码,但我将默认位置状态更改为 null,因为设置为零的经度和纬度值是有效坐标。

const geolocationGetCurrentPosition = () => {
  return new Promise((resolve, reject) => {
    const success = (position) => {
      const lat = position.coords.latitude;
      const long = position.coords.longitude;

      resolve({ lat, long });
    };
    const error = (err) => {
      reject(err);
    };
    navigator.geolocation.getCurrentPosition(success, error);
  });
};

const useLocation = () => {
  const [location, setLocation] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const { lat, long } = await geolocationGetCurrentPosition();
        setLocation({ lat, long });
      } catch (err) {
        // err
      }
    }
    fetchData();
  }, []);

  return location;
};

function App() {
  const location = useLocation();

  const routes = ["nasa", "openweather", "zomato"];

  return (
    <div className="App">
      {location && (
        <Route exact path="/openweather">
          <Weather position={location} />
        </Route>
      )}
    </div>
  );
}

【讨论】:

    猜你喜欢
    • 2018-12-09
    • 2018-01-13
    • 2020-11-08
    • 2018-12-13
    • 2020-03-26
    • 1970-01-01
    • 2016-03-08
    • 2021-03-04
    • 2021-11-14
    相关资源
    最近更新 更多