我有一个useEffect钩子,它有一个函数callForcast(),它依赖于callWeather,所以当callWeather()函数运行时,callForcast()运行。callweather()是通过onClick和callForcast()调用的,我在useEffect()中添加了一个调用,但这会导致无限循环。
我怎样才能让这个函数运行一次。
useEffect (() => {
async function callForcast() {
const key = "";
// Get lat & lon from the previous data fetch
const lon = weatherData.coord.lon
const lat = weatherData.coord.lat
// Get forcast data
const forcastWeatherUrl = `https://api.openweathermap.org/data/2.5/forecast?lat=${lat}&lon=${lon}&units=metric&appid=${key}`
const forcastWeatherResponse = await fetch(forcastWeatherUrl);
if (!forcastWeatherResponse.ok) {
const message = `An error has occured: ${forcastWeatherResponse.status}`;
throw new Error(message);
}
const forcastDataResponse = await forcastWeatherResponse.json();
// Update state with the forcast data
setForcastData(forcastDataResponse);
}
// Causing infinite loop
callForcast();
}, [callWeather])
这是callForcast函数所依赖的
async function callWeather() {
const key = "";
// Get location by user
let location = formData.location;
// Url for current weather
const currentWeatherUrl = `https://api.openweathermap.org/data/2.5/weather?q=${location}&units=metric&appid=${key}`;
// Get the current weather
const currentWeatherResponse = await fetch(currentWeatherUrl);
if (!currentWeatherResponse.ok) {
// Return this message if an error
const message = `An error has occured: ${currentWeatherResponse.status}`;
throw new Error(message);
}
// Get data if no error
const weatherDataResponse = await currentWeatherResponse.json();
// Update state with data
setWeatherData(weatherDataResponse);
}
2条答案
按热度按时间mw3dktmi1#
为什么它依赖于
callWeather
?它不使用callWeather
。它一遍又一遍地执行,大概是因为无论
callWeather
是什么,它在每次渲染时都会改变(可能在每次渲染时都被重新声明和/或重新赋值)。如果此效果只应执行一次,请使用空依赖项数组:
这将仅在组件首次加载时执行一次效果。
或者...
当运行callWeather()函数时,callForcast()将运行
如果你想在每次调用
callWeather()
时都调用callForcast()
,那么useEffect
就是一个错误的工具。只需定义你想调用的函数,然后在你想调用它的时候调用它。例如:另一种可能性...
如果您有一个状态值 * 是 * 依赖关系,并且希望在依赖关系更改时随时调用效果,请将该状态值用作依赖关系:
型
或者...
如果此函数只需要其他操作提供的一些数据,请提供该数据。例如:
总的来说,您并不完全清楚在什么情况下需要执行
callForcast
。(尽管在我键入此内容时,您可能会在问题中澄清这一点。)但是,* 在您的原始代码中 *,它在每个渲染上执行的原因是因为callWeather
在每个渲染上都在更改,并且 * 肯定 * 是错误的依赖项。1rhkuytd2#
尝试在效果中调用
callWeather
。如果是异步的,可以在callForcast中调用此外,你应该只是有
callWeather
返回你的数据在一个承诺,所以你可以提取它在你的callForcast
fn.像const data = await callWeather();
编辑:查看您可能需要的更新
或
型