Lumen
Lumen

Reputation: 139

Map functions & continous rerendering with UseEffect

When I call the below code in my React app, I get a continuous flow of updates to Console of 'forecasts'. I think this has something to do with the reference made in my mapping of zippedforecasts?

How do I prevent this loop of state changes for 'forecasts'?

function App() {
    const [dailyforecasts, setDailyforecasts] 
    const [hourlyforecasts, setHourlyforecasts
    const [forecasts, setForecasts] = useState

    useEffect(() => {
        axios.get('https://api.openweathermap.
            params: {
                lat: 37.773972,
                lon: -122.431297,
                appid: API_Key,
                units: "imperial",
            }
    })      
            .then(
                res => {
                const newDailyforecasts = res.
                    .map(obj => obj)

                setDailyforecasts(newDailyfore

                const newHourlyforecasts = res
                    .map(obj => obj)

                const current_hour = new Date(
                const day1 = newHourlyforecast
                const day2 = newHourlyforecast
current_hour))) 
                const day3 = newHourlyforecast

                const newHFs = [day1, day2, da


                setHourlyforecasts(newHFs) 
                }
            )},[]);

    const zippedforecasts = dailyforecasts.map
        { 
            return (hourlyforecasts[index]) ?
                ({dailyForecast:day, hourlyFor
                ({dailyForecast:day})
        })      


    useEffect(() => {
        setForecasts(zippedforecasts)
    }, [zippedforecasts])
    console.log(forecasts)

Upvotes: 0

Views: 70

Answers (2)

Matt Aft
Matt Aft

Reputation: 8936

It's causing an infinite loop because zippedforecasts is being re-defined on every re-render which constantly triggers the second useEffect. You can memoize it so it only gets ran on changes.

    const zippedforecasts = useMemo(() => dailyforecasts.map((dailyForecast) => { 
            return (hourlyforecasts[index]) ?
                ({dailyForecast:day, hourlyFor // this looks to be cut off
                ({dailyForecast:day})
        }), [hourlyforecasts]);    


    useEffect(() => {
        setForecasts(zippedforecasts)
    }, [zippedforecasts])

Upvotes: 1

mfe
mfe

Reputation: 1208

You don't need to second useEffect. You passed zippedForecast which is created on each render. That's why you end up infinite loop.

Just call

 setForecasts(zippedforecasts) 

after zippedforecasts

Upvotes: 1

Related Questions