我正在从API检索JSON数据,然后将其存储为状态,当我尝试使用this.state
(例如,我写this.state.DetailData.title
)访问数据时,它可以正常工作,但是当我尝试访问时相同对象的嵌套数据(例如this.state.DetailData.location.address
)会引发错误:
TypeError:无法读取未定义的属性“地址”
这是我的代码:
import React from 'react'
import Caro from './Carousel'
import {
Container,
Row,
Col
} from 'reactstrap';
class Detail extends React.Component {
constructor(props)
{
super(props)
this.state = {
DetailData: []
}
}
componentDidMount() {
fetch('https://api.kloh.in/kloh/external/v1/activity/AID180917200010526C8LFJ4MEIE9CWGXZG4', {
method: 'GET'
})
.then((response) => response.json())
.then((data) => {
this.setState({
DetailData: data.response
})
console.log(typeof(this.state.DetailData));
})
}
render() {
return (
<div>
<Caro / >
<Container >
<Row >
<Col xs = "12" sm = {{size: 8, offset: 2 } md = {{size: 8, offset: 2}} >
< div >
<h1> {this.state.DetailData.title} <h1>
<h1> {this.state.DetailData.location.address} </h1> {/*getting error here*/}
<hr/>
<h6> {this.state.DetailData.description} </h6>
</div>
</Col>
</Row>
</Container>
</div>
);
}
}
export default Detail;
答案 0 :(得分:3)
在安装组件时,尚未获取您的数据,因此this.state.DetailData是一个空对象,而this.state.DetailData.location确实是未定义的。
要解决此问题,您可以尝试在显示对象之前检查该对象是否存在。像这样:
{this.state.DetailData.location ? this.state.DetailData.location.address : ""}
您还应该检查为什么在初始化组件时却将DetailData定义为数组,而似乎却期望有一个对象。
this.state = {
DetailData: [] // this should be DetailData: {} or DetailData: null
}
答案 1 :(得分:0)
查看https://api.kloh.in/kloh/external/v1/activity/AID180917200010526C8LFJ4MEIE9CWGXZG4,有时location
字段为空,因此您需要进行检查。
答案 2 :(得分:0)
为避免这种情况,建议您使用
https://lodash.com/docs/4.17.10#get
这是获取深层嵌套属性值的一种更干净的方法。安装lodash并将其导入,然后使用
import React from 'react'
import Caro from './Carousel'
import {
Container,
Row,
Col
} from 'reactstrap';
import _ from 'lodash';
class Detail extends React.Component {
constructor(props)
{
super(props)
this.state = {
DetailData: []
}
}
componentDidMount() {
fetch('https://api.kloh.in/kloh/external/v1/activity/AID180917200010526C8LFJ4MEIE9CWGXZG4', {
method: 'GET'
})
.then((response) => response.json())
.then((data) => {
this.setState({
DetailData: data.response
})
console.log(typeof(this.state.DetailData));
})
}
render() {
return (
<div>
<Caro / >
<Container >
<Row >
<Col xs = "12" sm = {{size: 8, offset: 2 } md = {{size: 8, offset: 2}} >
< div >
<h1> {_.get(this.state, 'DetailData.title', 'any_default_value_for_title')} <h1>
<h1> {_.get(this.state, 'DetailData.location.address', 'any_default_value_for_address')} </h1> {/*getting error here*/}
<hr/>
<h6> {_.get(this.state, 'DetailData.description', 'any_default_value_for_description')} </h6>
</div>
</Col>
</Row>
</Container>
</div>
);
}
}
export default Detail;
这将为您的项目添加一个库。但这是干净的方法。
答案 3 :(得分:0)
您的渲染方法在ComponentDidMount函数之前运行,因此在那里使用了初始状态,其中this.state.DetailedData
是一个空数组,因此this.state.DetailData.location
是未定义的,您无法检查{{1} },而不会出现错误,因此您需要检查该位置是否存在
答案 4 :(得分:0)
使用 react、react-redux、useSelector
useSelector 是替代 mapstatetoprops 的钩子
我发现我无法映射嵌套对象 'typeerror 无法读取未定义的属性'
我的数据看起来像这样
orderDetails:{loading:_, error:_, order:{etc:_,items:[...,{etc:_}]}
错误
useEffect(()=>{...dispatch()},[])
const orderDetails = useSelector(state=>state.orderDetails)
const {order, loading, error}= orderDetails;
通过使用 useSelector 和选择更深层次的状态与解构来工作
const order = useSelector(state=>state.orderDetails.order)