从props访问数组返回undefined

问题描述 投票:0回答:2

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]')

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

javascript reactjs jsx
2个回答
0
投票

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

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

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

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


0
投票

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

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

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

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'));
<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>
© www.soinside.com 2019 - 2024. All rights reserved.