我想练习我的reactjs技能,所以我正在通过流行的openweathermap api的api调用进行一些练习
我正在componentDidMount()周期中进行api调用,该周期遵循文档here,是进行异步调用的更好位置
如果我在渲染中使用console.log(data),我首先会变得不确定,然后会得到所需的对象;但是,如果我尝试使用确实存在的{data.city.name}访问该对象,则会在第二次重新渲染时收到错误“ TypeError:无法读取未定义的属性'name'”(componentDidMount()强制进行第二次渲染)
我不知道自己缺少什么,我对生命周期没有经验,但这很简单,我不明白为什么会这样
有人可以启发我吗?谢谢。
import React from 'react';
class WeekForecast extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
data: {}
};
}
componentDidMount() {
fetch([url])
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
data: result
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
const { data } = this.state;
return(
<div>
<p>This weeks forecast in {data.city.name}</p>
</div>
)
}
}
export default WeekForecast;
答案 0 :(得分:1)
希望以下代码段有所帮助。 几个问题。
class WeekForecast extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
data: {}
};
}
fetch = () => Promise.resolve({city:{name:"New York City"}})
componentDidMount() {
this.fetch()
.then(
(result) => {
this.setState({
isLoaded: true,
data: result
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
const { data } = this.state;
return(
<div>
<p>This weeks forecast in {data.city && data.city.name || 'No City'}</p>
</div>
)
}
}
ReactDOM.render(<WeekForecast />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>
答案 1 :(得分:1)
您看到此错误,因为您正试图从undefined
对象获取属性。如果您当时尝试记录undefined
的属性是没有问题的,但是如果尝试从此undefined
对象获取属性,则会收到错误消息。
const data = {};
console.log( "city is", data.city );
console.log( "city name is", data.city.name );
这是另一个例子。如果我们没有为data
定义一个空对象怎么办?您是在自己的州定义一个,但是如果我们不定义该怎么办?
//const data = {};
console.log( "city is", data.city );
console.log( "city name is", data.city.name );
由于未定义data
,因此无法将city
作为undefined
。
在您的情况下,data
在您的状态中定义为空对象。因此,尝试记录city
会返回undefined
,但是尝试记录city.name
会返回错误。
由于在第一个渲染后数据将降落在组件中,因此应使用条件渲染检查数据是否存在。当您处理来自遥远地方的数据时,将一直使用它。有很多方法可以进行条件渲染。这是其中之一:
renderHelper() {
const { data } = this.state;
if ( !data.city ) { return <p>Loading data...</p>}
return <p>This weeks forecast in {data.city.name}</p>
}
render() {
return (
<div>
{ this.renderHelper() }
</div>
)
}