尝试访问React.js中的嵌套对象时出现错误

时间:2018-09-20 13:38:35

标签: javascript reactjs

我正在从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;

5 个答案:

答案 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)