【发布时间】:2021-07-17 10:05:40
【问题描述】:
我正在创建一个简单的天气应用程序来巩固我的反应挂钩知识。使用 useEffect 时,我在使用异步等待函数时不断出现错误。我环顾四周,找到了在使用效果中一次性使用异步函数的方法。
我的问题是我想使用 async/await 函数两次。我使用 navigator.geolocation 来查找当前位置并设置 lat 和 long 状态。然后,一旦它们被设置,运行一个天气 api,它使用新的纬度和经度状态。我在这里找到了多个关于如何设置状态等待下一次渲染的解决方案,因此在下一个 fetchAPI 函数中使用新设置的状态将不起作用。
因此,我想出了这个解决方案。
const [lat, setLat] = useState([]);
const [long, setLong] = useState([]);
const [data, setData] = useState();
useEffect(() => {
fetchLocation(/*uses navigator.geolocation to setLong and setLat*/);
// hacked out a way to not call fetch data until lat and long are set.
if (typeof lat == "number" && typeof long == "number") {
fetchWeatherData();
}
console.log(lat, "<= lat");
console.log(long, "<= long");
}, [lat, long]);
这个解决方案就像我在 localhost 上想要的那样工作,因为它只在使用第一个函数设置 lat 和 long 状态时获取 weatherAPI。在 useEffect 加载 WeatherAPI 之前,lat 和 long 仍然设置为空,从而导致错误。 我想知道这是否是解决此问题的正确方法,或者是否存在我尚未发现的未知副作用。
之后还会弹出此警告,我不确定如何处理。
"src/App.js 第 37:6 行:React Hook useEffect 缺少依赖项:'fetchWeatherData'。要么包含它,要么移除依赖数组 react-hooks/exhaustive-deps"
编辑:cmets 要求的完整代码
import React, { useState, useEffect } from "react";
import WeatherDisplay from "./weather";
require("dotenv").config();
function App() {
const [lat, setLat] = useState([]);
const [long, setLong] = useState([]);
const [data, setData] = useState();
const fetchLocation = () => {
navigator.geolocation.getCurrentPosition((position) => {
setLat(position.coords.latitude);
setLong(position.coords.longitude);
});
};
const fetchWeatherData = () => {
fetch(
`${process.env.REACT_APP_API_URL}/weather/?lat=${lat}&lon=${long}&units=metric&APPID=${process.env.REACT_APP_API_KEY}`
)
.then((res) => res.json())
.then((result) => {
setData(result);
console.log(result);
});
};
useEffect(() => {
fetchLocation();
// hacked out a way to not call fetch data until lat and long are set.
if (typeof lat == "number" && typeof long == "number") {
fetchWeatherData();
}
console.log(lat, "<= lat");
console.log(long, "<= long");
}, [lat, long]); // set as empty arrays if locations don't work
return (
<div className="App">
{/* data is the data that was fetched from fetchWeatherData() */}
<WeatherDisplay weatherData={data} />
</div>
);
}
export default App;
【问题讨论】:
-
你能分享完整的代码,这样我们可以做得更好。
-
传递给
useEffect的函数在其任何依赖项发生更改时运行。所以是的,正确的方法是使用带有空依赖数组的 useEffect 挂钩来启动地理位置,然后使用带有[lat, long]的挂钩来加载天气数据。我不确定到底是什么问题,主要是因为您删除了很多相关代码。 -
对不起,我现在添加了完整的代码
标签: javascript reactjs use-effect