如何修复 WebApp 保持呈现状态?
How to fix WebApp keeps rendering state?
我正在使用 React 和 Hooks 设置一个简单的天气应用程序。但是,我发现该应用程序一直在获取 API。我怎样才能阻止这个?
function WeatherInfo (props) {
const [wind,setWind] = useState(undefined);
const [precipitation,setPrecipitation] = useState(undefined);
const [humidity,setHumidity] = useState(undefined);
const [pressure,setPressure] = useState(undefined);
if (props.city) {
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setWind(data.wind.speed))
})
useEffect(() => {
fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setPressure(data.main.pressure))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setHumidity(data.main.humidity))
})
}
return (
<div>
{props.city &&
<div>
<p>Wind of {props.city} is {wind}</p>
<p>Chance of rain of {props.city} is {precipitation}%</p>
<p>Humidity of {props.city} is {humidity}</p>
<p>Pressure of {props.city} is {pressure}</p>
</div>
}
</div>
)
}
export default WeatherInfo;
预期结果:函数仅获取 API 一次
默认情况下,useEffect
挂钩在每次重新渲染时都是 运行。如果你不想这样,你可以指定第二个可选参数,见 https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects.
在你的具体情况下:你可能只想在城市改变时执行效果,所以:
useEffect(/* callbacks as before */, [props.city])
.
此外,您应该只在顶层调用挂钩(即不在 ifs 中):https://reactjs.org/docs/hooks-overview.html#%EF%B8%8F-rules-of-hooks。您可以将 if 分支移动到 useEffect
的回调中
您可以使用 setInterval 来限制代码运行的频率,例如
setInterval(function(){
if (props.city) {
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setWind(data.wind.speed))
})
useEffect(() => {
fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setPressure(data.main.pressure))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setHumidity(data.main.humidity))
})}}, 10000);
然后只需根据您希望它检查的频率调整时间
我正在使用 React 和 Hooks 设置一个简单的天气应用程序。但是,我发现该应用程序一直在获取 API。我怎样才能阻止这个?
function WeatherInfo (props) {
const [wind,setWind] = useState(undefined);
const [precipitation,setPrecipitation] = useState(undefined);
const [humidity,setHumidity] = useState(undefined);
const [pressure,setPressure] = useState(undefined);
if (props.city) {
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setWind(data.wind.speed))
})
useEffect(() => {
fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setPressure(data.main.pressure))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setHumidity(data.main.humidity))
})
}
return (
<div>
{props.city &&
<div>
<p>Wind of {props.city} is {wind}</p>
<p>Chance of rain of {props.city} is {precipitation}%</p>
<p>Humidity of {props.city} is {humidity}</p>
<p>Pressure of {props.city} is {pressure}</p>
</div>
}
</div>
)
}
export default WeatherInfo;
预期结果:函数仅获取 API 一次
默认情况下,useEffect
挂钩在每次重新渲染时都是 运行。如果你不想这样,你可以指定第二个可选参数,见 https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects.
在你的具体情况下:你可能只想在城市改变时执行效果,所以:
useEffect(/* callbacks as before */, [props.city])
.
此外,您应该只在顶层调用挂钩(即不在 ifs 中):https://reactjs.org/docs/hooks-overview.html#%EF%B8%8F-rules-of-hooks。您可以将 if 分支移动到 useEffect
的回调中您可以使用 setInterval 来限制代码运行的频率,例如
setInterval(function(){
if (props.city) {
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setWind(data.wind.speed))
})
useEffect(() => {
fetch(`https://api.worldweatheronline.com/premium/v1/weather.ashx?key=a5bf94fc16c84928acb114156182311&q=${props.city}&num_of_days=1&tp=24&format=json`).then(results => {return results.json();}
).then(data => setPrecipitation(data.data.weather[0].hourly[0].chanceofrain))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setPressure(data.main.pressure))
})
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${props.city}&units=metric&APPID=af081727ae6d5c4cbe2cd266b726e632`).then(results => {return results.json();}
).then(data => setHumidity(data.main.humidity))
})}}, 10000);
然后只需根据您希望它检查的频率调整时间