带有axios的react useEffect挂钩无法读取未定义的属性

问题描述 投票:0回答:1

这是基于本课程https://fullstackopen.com/en/part2/getting_data_from_server的练习2.14。

用户可以选择一个国家,然后将显示该国家首都的天气信息。我的代码给我错误无法读取未定义的属性'温度'

const Weather = ({ city }) => {
const [weatherDetails, setWeatherDetails] = useState([])

useEffect(() => {
    axios.get('http://api.weatherstack.com/current', {
        params: {
            access_key: process.env.REACT_APP_WEATHER_KEY,
            query: city
        }
    }).then(
        (response) => {
            setWeatherDetails(response.data)
        }
    )
}, [city])
console.log('weather', weatherDetails);

return (
    <div>
        <h3>Weather in {city} </h3>
        {weatherDetails.current.temperature}
    </div>
)}

基本上是直线

{weatherDetails.current.temperature}

使我的代码崩溃。当我确实删除该行时,由于console.log,我能够看到响应,但是有两个连续的日志

weather []
weather {request: {…}, location: {…}, current: {…}}

我发现我的代码发生在这两者之间,并且它试图在数据到达之前就访问数据,但是我不知道该如何解决。

而且,我也不知道useEffect()的参数[city]的作用,所以如果有人可以向我解释它的作用,那就太好了。

编辑:已解决!将weatherDetail的初始状态设置为null并进行一些条件渲染

if (weatherDetails) {
    return (
        <div>
            <h3>Weather in {capital}</h3>
            {weatherDetails.current.temperature} Celsius
        </div>
    )
} else {
    return (
        <div>
            Loading Weather...
        </div>
    )
}
reactjs axios react-hooks
1个回答
2
投票

[weatherDetails最初是一个空数组,所以没有要读取的current属性。

使用一些conditional rendering。使用初始空状态,然后检查在更新对象时是否可以访问该对象的其余部分。

const Weather = ({ city }) => {
const [weatherDetails, setWeatherDetails] = useState(null) // <-- use null initial state

useEffect(() => {
    axios.get('http://api.weatherstack.com/current', {
        params: {
            access_key: process.env.REACT_APP_WEATHER_KEY,
            query: city
        }
    }).then(
        (response) => {
            setWeatherDetails(response.data)
        }
    )
}, [city])
console.log('weather', weatherDetails);

return (
    <div>
        <h3>Weather in {capital} </h3>
        {weatherDetails && weatherDetails.current.temperature} // check that weatherDetails exists before accessing properties.
    </div>
)}

[city]的参数useEffect有什么作用?

这是挂钩的依赖项数组。挂钩在每个渲染周期运行,如果依赖项数组中的任何值已更新,它将触发挂钩的回调,在这种情况下,将触发city道具更新时获取天气数据的效果。

useEffect

默认情况下,效果会在每个完成的渲染后运行,但是您可以 选择仅在某些值已更改时才触发它们。

© www.soinside.com 2019 - 2024. All rights reserved.