【发布时间】:2020-11-06 16:36:28
【问题描述】:
我试图通过 API 调用访问 OpenWeatherMap 中的天气信息,但我总是收到“无法读取未定义的属性”错误。
在我的 App.js 文件中,我有一个 CallAPI 函数,用于传递用户坐标并获取天气数据。然后它会被传递给我的 Header 组件,其 prop 为“curr”。
const [currWeatherData, setCurrWeatherData] = useState({})
useEffect(() => {
navigator.geolocation.getCurrentPosition(CallAPI, showError);
}, [])
//... showError function
function CallAPI(position){
const lat = position.coords.latitude
const long = position.coords.longitude
fetch(/*api call*/)
.then(response => response.json())
.then(data => {
setCurrWeatherData(data.current)
})
}
return (
<div>
<Header curr = {currWeatherData}/>
<div>
)
在我的 Header.js 文件中,我目前只是想显示天气状态。
import React from "react"
function Header(props){
return(
<div>
{/*<h1>{props.curr.weather[0].main}</h1>*/}
{console.log(props.curr.weather)}
</div>
)
}
API 中 json 文件的开头如下所示。
在“current”中,有一个天气属性是一个数组,其中一个元素是一个对象,因此我假设访问“main”属性的正确方法是“current.weather[0].main ”。但是,当我尝试 console.log 或返回它时,我收到错误“无法读取未定义的属性 '0'”。奇怪的是,当我 console.log "current.weather" 时,它会在控制台上打印一个带有对象的数组。
我尝试在访问变量的第 0 个索引之前将“current.weather”存储在变量中,并且尝试将“currWeatherData.weather”作为我的 App.js 文件中的道具传递,我不认为这两者改变任何东西。我真的不知道从这里去哪里,有人可以帮忙吗?
编辑:经过一个小时左右的 console.log 调试后,我发现了我的问题。我了解到,当使用钩子时,useState 触发重新渲染的方式与 this.setState 相同,这意味着每次我设置状态时,它都会渲染我的 Header 组件。我猜 API 调用在渲染之前没有完成,所以 prop 以未定义的形式传递。我通过添加一个 isLoading 状态并在 API 调用后将其设置为 false 解决了这个问题,
//... code above
.then(data => {
setCurrWeatherData(data.current)
setIsLoading(false)
})
在我的回报中,我添加了一个条件语句
<div>
{!isLoading && <Header curr = {currWeatherData}/>}
</div>
我浏览了https://medium.com/swlh/how-does-react-hooks-re-renders-a-function-component-cc9b531ae7f0 以提供帮助
【问题讨论】:
标签: javascript json reactjs