REACT 16.3 - 渲染道具数组作为地图(可选)

时间:2018-05-28 12:31:25

标签: javascript arrays reactjs

我正在尝试渲染一个由props提供的映射数组。问题是阵列并不总是可用,具体取决于父级的状态。如果我尝试将地图应用于不存在的数组,我会收到错误(当然!)。所以我试图设置一个默认的空数组来克服错误。

如果我设置默认REACT认为我正在尝试映射一个对象。以下代码已经过简化,但最终结果是相同的:

export class Parent extends Component {

    constructor(props) {
        super(props);
        this.state = {
            // This array is not always available
            // It's actually a deep property in an object
            // done here for simplicity
            myArray: [{name: 'foo'},{name: 'bar'}],
        };
    }

    render() {
        return (
            <Child myArray={this.state.myArray} />
        );
    }

} 


import React, { Component } from 'react';

export class Child extends Component {

    render() {

        console.log(this.props.myArray); //=> [{...},{...}] Array
        console.log(typeof this.props.myArray); //=> Object (wuh???)

        this.props.myArray.map((item) => console.log(item.name)); //=> 'foo' then 'bar'

        // Supply a default empty array here to avoid mapping an undefined
        const list = this.props.myArray || [];

        list.map((item) => {
            return (
                <li key={item.name}>{item.name}</li>
            );
        });

        return (
            <ul> {list} </ul>
        );
    }

}
  

未捕获错误:对象作为React子对象无效(找到:具有键{name}的对象)。如果您要渲染子集合,请改用数组。

如果我对数组进行硬编码并省略了默认的空数组,我就不会收到错误:

const list = this.props.myArray.map((item) => {
            return (
                <li key={item.name}>{item.name}</li>
            );
        });

关于如何将地图应用于条件数组的任何想法?

2 个答案:

答案 0 :(得分:2)

.map返回一个新数组而不是修改现有数组(你不应该这样做,因为道具只是为了只读)。

您可以将.map分配给新变量,或直接在JSX中进行映射:

<ul>{list.map(item => <li key={item.name}>{item.name}</li>)}</ul>

您也可以执行{(this.props.myArray || []).map(...)}或使用默认道具,或使用[](而不是null等)作为与props.myArray对应的父组件中的初始状态。

答案 1 :(得分:1)

将Child组件的默认道具用作空数组:

import React, { Component } from 'react';

export class Child extends Component {
    render() {
        const list = this.props.myArray.map((item) =>(
            <li key={item.name}>{item.name}</li>
        ));

        return (
            <ul> {list} </ul>
        );
    }
}

Child.defaultProps = {
    myArray: []
};