The goal is to display different backgrounds depending on the fetched weather data. I'm trying to set the background inline in the JSX. On the first fetch, the data is populated but the background doesn't change until I click the search icon again. I've tried bundling both the fetch function and background handler function in one function then setting that function onClick and I've tried adding the backgroundHandler at the end of the fetch function. Both require an additional click after the initial fetch. On each occasion, you can see a 404 error on the initial fetch to populate the data. The photo I'm testing is imported into React as (cloudy).
Both Functions bundled into RenderUI Function
const WeatherContainer = () => {
const [searchTerm, setsearchTerm] = useState()
const [currentWeather, setCurrentWeather] = useState({});
const [forecastedWeather, setForecastedWeather] = useState({});
const [loading, setLoading] = useState(false);
const [background, setBackground] = useState()
const handleInput = (e) => {
setsearchTerm(e.target.value);
}
// Dynamically changes background depending on current weather
const backgroundHandler = () => {
// Day Backgrounds
if (Object.keys(currentWeather).length > 0) {
if (currentWeather.weather[0].icon === '02d' || currentWeather.weather[0].icon === '04d' ) {
setBackground(cloudy)
}
}
};
const handleSearch = () => {
fetch(`/weather/${searchTerm}`)
.then(res => { return res.json() })
.then(result => {
setCurrentWeather({ ...result.data })
})
};
const renderUI = () => {
handleSearch();
backgroundHandler();
}
return (
<div>
<div className='search-bar'>
<input className='text_input' type='text' name='searchTerm' onChange={handleInput} placeholder='Enter city' />
<button className='search-button' onClick={renderUI} type='submit' value='submit' name='button'>
<Icon icon={searchIcon} flip="horizontal" />
</button>
</div>
<div className='weather-container' style={{ backgroundImage: `url(${background})` }}>
{Object.keys(currentWeather).length > 0
? <>
<CurrentWeatherComponent
currentWeather={currentWeather}/>
<ForecastContainer />
</>
: <></>
}
</div>
</div>
)
};
BackgroundHandler called at the end of handleSearch Function
const WeatherContainer = () => {
const [searchTerm, setsearchTerm] = useState()
const [currentWeather, setCurrentWeather] = useState({});
const [forecastedWeather, setForecastedWeather] = useState({});
const [loading, setLoading] = useState(false);
const [background, setBackground] = useState()
const handleInput = (e) => {
setsearchTerm(e.target.value);
}
// Dynamically changes background depending on current weather
const backgroundHandler = () => {
// Day Backgrounds
if (Object.keys(currentWeather).length > 0) {
if (currentWeather.weather[0].icon === '02d' || currentWeather.weather[0].icon === '04d' ) {
setBackground(cloudy)
}
}
};
const handleSearch = () => {
fetch(`/weather/${searchTerm}`)
.then(res => { return res.json() })
.then(result => {
setCurrentWeather({ ...result.data })
})
backgroundHandler();
};
return (
<div>
<div className='search-bar'>
<input className='text_input' type='text' name='searchTerm' onChange={handleInput} placeholder='Enter city' />
<button className='search-button' onClick={handleSearch} type='submit' value='submit' name='button'>
<Icon icon={searchIcon} flip="horizontal" />
</button>
</div>
<div className='weather-container' style={{ backgroundImage: `url(${background})` }}>
{Object.keys(currentWeather).length > 0
? <>
<CurrentWeatherComponent
currentWeather={currentWeather}/>
<ForecastContainer />
</>
: <></>
}
</div>
</div>
)
};
Change backgroundHandler
to a useEffect
with currentWeather
as a dependency (just copy the function body and put inside it). useState
is async and may not be set yet when you run backgroundWeather
, that's why its blank
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.