与 axios 反应 useEffect 钩子无法读取未定义的属性

dem*_*ace 0 reactjs axios react-hooks

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

\n\n

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

\n\n
const Weather = ({ city }) => {\nconst [weatherDetails, setWeatherDetails] = useState([])\n\nuseEffect(() => {\n    axios.get(\'http://api.weatherstack.com/current\', {\n        params: {\n            access_key: process.env.REACT_APP_WEATHER_KEY,\n            query: city\n        }\n    }).then(\n        (response) => {\n            setWeatherDetails(response.data)\n        }\n    )\n}, [city])\nconsole.log(\'weather\', weatherDetails);\n\nreturn (\n    <div>\n        <h3>Weather in {city} </h3>\n        {weatherDetails.current.temperature}\n    </div>\n)}\n
Run Code Online (Sandbox Code Playgroud)\n\n

基本上,该行

\n\n
{weatherDetails.current.temperature}\n
Run Code Online (Sandbox Code Playgroud)\n\n

使我的代码崩溃。当我删除该行时,我可以通过 console.log 看到响应,但有两个连续的日志

\n\n
weather []\nweather {request: {\xe2\x80\xa6}, location: {\xe2\x80\xa6}, current: {\xe2\x80\xa6}}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我认为我的代码发生在这两者之间,并且它尝试在数据到达之前访问数据,但我不知道该怎么做才能解决这个问题。

\n\n

另外,我不知道 useEffect() 的参数 [city] 是做什么的,所以如果有人能向我解释它的作用那就太好了。

\n\n

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

\n\n
if (weatherDetails) {\n    return (\n        <div>\n            <h3>Weather in {capital}</h3>\n            {weatherDetails.current.temperature} Celsius\n        </div>\n    )\n} else {\n    return (\n        <div>\n            Loading Weather...\n        </div>\n    )\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Dre*_*ese 5

weatherDetails最初是一个空数组,因此没有可供current读取的属性。

使用一些条件渲染。使用初始空状态,然后检查更新时访问对象的其余部分是否为真。

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>
)}
Run Code Online (Sandbox Code Playgroud)

[city]的论证有什么useEffect作用?

这是钩子的依赖数组。挂钩在每个渲染周期上运行,如果依赖项数组中的任何值已更新,则会触发挂钩的回调,在本例中,效果是在道具city更新时获取天气数据。

使用效果

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