【问题标题】:Accessing array from props is returning undefined从道具访问数组返回未定义
【发布时间】:2018-06-03 11:39:51
【问题描述】:

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

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

【问题讨论】:

  • info 是异步获取的吗?
  • @Max 是的,它正在被获取并设置在一个单独的处理函数中

标签: javascript reactjs jsx


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    这是一个正在运行的带有您的代码的 sn-p,请注意,您必须将 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>

    【讨论】:

      猜你喜欢
      • 2018-09-02
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      • 2020-01-16
      • 2020-12-05
      • 2021-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多