这是我编写的代码,用于根据用户输入更改背景视频。背景具有基于用户输入位置的天气的视频。
import React, { Fragment, useState, useEffect } from "react";
import cloudy from "../assets/cloudy.mp4";
import sunny from "../assets/sunny.mp4";
import rainy from "../assets/rainy.mp4";
import winter from "../assets/winter.mp4";
const weathers = [cloudy, sunny, rainy, winter];
const Background = (props) => {
const [weather, setWeather] = useState(weathers[1]);
const temp = props.info.current.temp_c;
const rain = props.info.current.precip_mm;
if (rain > 2.5) setWeather(weathers[2]);
else if (temp < 8) setWeather(weathers[3]);
return (
<Fragment>
<video autoPlay loop muted className="back-video">
<source src={weather} type="video/mp4" />
</video>
</Fragment>
);
}
下面是我在App组件中的返回方式:
return (
<Fragment>
<div className="container">
<h1>Weather App</h1>
<Input newLocation={locationHandler} />
<article>{content}</article>
</div>
<article>{background}</article>
</Fragment>
)
我尝试使用UseEffect,因为我有一个重新渲染错误,但在这种情况下,它根本不会改变背景
useEffect(() => {
if (rain > 2.5) setWeather(weathers[2]);
else if (temp < 8) setWeather(weathers[3]);
}, [weather, temp, rain])
或者仅将天气作为依赖项。
编辑:我的应用程序组件
import React, { useState, useEffect, useCallback, Fragment } from
"react";
import Background from "./components/Background";
import Weather from "./components/Weather";
import Input from "./UI/Input";
function App() {
const [weather, setWeather] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const [location, newLocation] = useState("New Delhi");
const locationHandler = (place) => {
newLocation(place);
};
const fetchweatherHandler = useCallback(async () => {
setIsLoading(true);
setError(null);
try {
//console.log(location);
const response = await fetch(
`http://api.weatherapi.com/v1/current.json?
key={apiKey}&q=${location}&aqi=yes`
);
if (!response.ok) {
throw new Error("Something went wrong!");
}
const data = await response.json();
//console.log(data);
setWeather(data);
} catch (error) {
setError(error.message);
}
setIsLoading(false);
}, [location]);
useEffect(() => {
fetchweatherHandler();
}, [fetchweatherHandler]);
let content = <p>Found no weather.</p>;
let background = <p>No Background</p>;
if (weather && Object.keys(weather).length > 0) {
content = weather && <Weather info={weather} />;
background = weather && <Background info={weather} />;
}
if (error) {
content = <p>{error}</p>;
}
if (isLoading) {
content = <p>Loading...</p>;
}
return (
<Fragment>
<div className="container">
<h1>Weather App</h1>
<Input newLoc={locationHandler} />
<article>{content}</article>
</div>
<article>{background}</article>
</Fragment>
);
}
export default App;
1条答案
按热度按时间0lvr5msh1#
UseEffect
的工作原理是这样的:无论你在[]
中传递了哪个状态,useEffect都会监听它的状态,只要状态发生变化,它就会执行useEffect中的代码。在你的例子中,你传递了
[weather]
,在useEffect
中你改变了setWeather
,这改变了weather
,所以useEffect
再次运行,这又是weather
的集合,它继续导致无限循环,并导致太多的重新呈现错误。您可以像下面这样使用它,但它不会在每次天气变化时重新渲染。
查看主题
lifecycle of components in react functional components
了解更多信息