React.js如何循环遍历数组?

37

我正在尝试展示一个由10个玩家组成的表格。我通过ajax获取数据并将其作为props传递给我的子组件。

var CurrentGame = React.createClass({

  // get game info
  loadGameData: function() {
    $.ajax({
      url: '/example.json',
      dataType: 'json',
      success: function(data) {
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err) {
        console.error('#GET Error', status, err.toString());
      }.bind(this)
    });
  },

  getInitialState: function(){
    return {data: []};
  },

  componentDidMount: function() {
    this.loadGameData();
  },

  render: function() {
    return (
      <div className="CurrentGame">
        <h1> Current Game Information</h1>
        <PlayerList data={this.state.data}/>
      </div>
    );
  }
});

现在我需要一个列表组件来渲染玩家:

var PlayerList = React.createClass({


  render: function() {

    // This prints the correct data
    console.log(this.props.data);

    return (
      <ul className="PlayerList">
        // I'm the Player List {this.props.data}
        // <Player author="The Mini John" />

        {
          this.props.data.participants.map(function(player) {
            return <li key={player}>{player}</li>
          })
        }
      </ul>
    )
  }
});

这给了我一个 Uncaught TypeError: Cannot read property 'map' of undefined 的错误。

我有点不确定发生了什么,我的控制台日志显示了正确的数据,但是在返回中无法访问它。

我错过了什么?

3个回答

41

CurrentGame 组件中,您需要更改初始状态,因为您尝试使用循环处理 participants,但是该属性是 undefined,这就是为什么会出现错误的原因。

getInitialState: function(){
    return {
       data: {
          participants: [] 
       }
    };
},

另外,由于.map中的playerObject,所以您应该从中获取属性

this.props.data.participants.map(function(player) {
   return <li key={player.championId}>{player.summonerName}</li>
   // -------------------^^^^^^^^^^^---------^^^^^^^^^^^^^^
})

示例


你能为每个列表项添加onClick事件并将列表项传递给函数吗?在函数中打印数据? - Kiran

17

正如@Alexander所解决的那样,这个问题是异步数据加载的一个问题 - 你立即进行渲染,而在异步Ajax调用解析并填充dataparticipants之前,你将无法加载参与者。

提供的替代方案将防止参与者存在之前进行渲染,像这样:

    render: function() {
        if (!this.props.data.participants) {
            return null;
        }
        return (
            <ul className="PlayerList">
            // I'm the Player List {this.props.data}
            // <Player author="The Mini John" />
            {
                this.props.data.participants.map(function(player) {
                    return <li key={player}>{player}</li>
                })
            }
            </ul>
        );
    }

1
你可以在进行map操作之前进行条件检查,例如:
{Array.isArray(this.props.data.participants) && this.props.data.participants.map(function(player) {
   return <li key={player.championId}>{player.summonerName}</li>
   })
}

现在,.map可以通过两种不同的方式完成,但仍需要条件检查,例如:
.map带有返回值
{Array.isArray(this.props.data.participants) && this.props.data.participants.map(player => {
   return <li key={player.championId}>{player.summonerName}</li>
 })
}

.map没有返回值

{Array.isArray(this.props.data.participants) && this.props.data.participants.map(player => (
   return <li key={player.championId}>{player.summonerName}</li>
 ))
}

上述两个功能是相同的


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接