关于与异步函数相关的 React 组件 运行 的顺序问题
Question About Which Order React Components Run In Relation To Async Functions
我有一个应用程序,在用户加载它时,使用 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()
},[])
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 中,并将 resolve 放在 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")
}
这是结果代码,但我将默认位置状态更改为空,因为经度和纬度值设置为零是有效坐标。
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>
);
}
我有一个应用程序,在用户加载它时,使用 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()
},[])
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 中,并将 resolve 放在 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")
}
这是结果代码,但我将默认位置状态更改为空,因为经度和纬度值设置为零是有效坐标。
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>
);
}