简体   繁体   中英

useEffect not re-rendering after state change

I am building a little side project to get more familiar with Hooks and I am running into a problem right now:

The project is a weather app, pulling weather data for a city from an API. The code below is a simplified version of the app. \\

import React, { useState, useEffect } from "react"
import axios from "axios"

const App: React.FC = () => {
    const [weather, setWeather] = useState<any>({})
    const [city, setCity] = useState<string>("London")
    const [cities, setCities] = useState<string[]>([
        "London",
        "New York",
        "Dubai",
        "Berlin",
        "Los Angeles",
        "Sydney",
    ])

    useEffect(() => {
        axios.get(`https://api-url/?query=${city}`)
            .then(res => setWeather(res.data))
            .catch ...
    }, [])

    return (
        <Drawer>
            <nav>
                <ul>
                    {cities.map((c, i) => (
                        <li key={i} onClick={() => setCity(c)}>
                            {c}
                        </li>
                    ))}
                </ul>
            </nav>
        </Drawer>
        // more JSX to display weather data for current city
    )
}

Expected behaviour: Clicking on li elements sets the state of city to the new city and rerenders the UI, loading the weather data for the selected city.

Actual behavour: State gets set, but app doesn't reload the data.

You need to specify city as the dependency, telling when to re-execute the effect.

See Conditionally firing an effect for more details about the [] argument.

useEffect(() => {
    axios.get(`https://api-url/?query=${city}`)
        .then(res => setWeather(res.data))
        .catch ...
}, [city])

Also see ESLint plugin for Rules of Hooks and Exhaustive Deps.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM