从props访问数组返回undefined

时间:2017-12-20 20:38:53

标签: javascript reactjs jsx

App.js我有一个组件,我传递了一些道具:

<Populated
      addressParts={this.state.info}
 />

this.state.info是一个包含其他对象的对象:

title: 'blahblahblah'
details: Array(3)

......等等......

details包含以下字段:

name: 'this is a question'
levelOfDifficulty: 100000

......等等......

我的代码如下:

import React from 'react'

class Populated extends React.Component {

  render() {
    return(
      <h1>{this.props.addressParts.title}</h1>
    )
  }
}

export default Populated

但是,即使我尝试console.log this.props.addressParts.details [0] .name,我也会收到以下错误:

TypeError: undefined is not an object (evaluating 'this.props.addressParts.details[0]')

我在这里做错了什么?我是否需要以某种方式将道具映射到初始状态?提前谢谢。

2 个答案:

答案 0 :(得分:0)

假设您正在正确传递道具,您将收到错误,因为该组件在数据获取之前呈现并尝试访问this.props.addressParts.details[0]。为了避免抛出错误,您可以将它放在导致错误的组件的render方法的最顶层:

if (!this.props.addressParts) return null;

获取数据并更新道具后,组件将重新渲染。

如果_.get(this.props, 'addressParts.details[0]')未定义,您还可以使用lodash this.props.addressParts返回undefined而不是抛出错误。

答案 1 :(得分:0)

您没有在第一次渲染调用中提供道具,因为您在异步获取数据后设置状态。

您可以在Populated组件内或App组件内执行conditional rendering

以下是您的代码的运行代码段,请注意您必须将info启动为null,以便我所做的当前条件能够正常运行。你可以用其他方式和其他条件来做,这只是其中之一。

&#13;
&#13;
class Populated extends React.Component {

  render() {
    const { addressParts } = this.props || {}; // just in case you want do defualt to an empty object
    return (
      <div>
        <h1>{addressParts.title}</h1>
        <h2>{addressParts.details.name}</h2>
        <h3>{addressParts.details.levelOfDifficulty}</h3>
      </div>
    )
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      // you must initilize info to null so the current condition will work
      info: null
    }
  }

  componentDidMount() {
    // just mimic an async fetch here
    setTimeout(() => {
      this.setState({
        info: {
          title: 'im here',
          details: {
            name: 'this is a question',
            levelOfDifficulty: 100000
          }
        }
      })
    }, 1200);
  }

  render() {
    const { info } = this.state;
    return (
      <div>
        {
          info ?
            <Populated addressParts={this.state.info} /> :
            <div>Loading data...</div>
        }
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById('root'));
&#13;
<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="root"></div>
&#13;
&#13;
&#13;