web-dev-qa-db-ja.com

React.jsは配列を介してループを作成します

10人のプレイヤーのテーブルを表示しようとしています。 ajaxからデータを取得し、小道具としてChildに渡します。

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を与えます。

何が起こっているのかわからないのですが、コンソールログには正しいデータが表示されますが、どういうわけかそのデータにアクセスできません。

私は何が欠けていますか?

33
Mini John

CurrentGameコンポーネントでは、participantsのループを使用しようとしているため、初期状態を変更する必要がありますが、このプロパティはundefinedであるため、エラーが発生します。

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

また、.mapplayerObjectであるため、そこからプロパティを取得する必要があります

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

Example

39
Alexander T.

@Alexanderが解決すると、問題は非同期データロードの1つになります-すぐにレンダリングされ、非同期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>
        );
    }
16
Dan W

次のようなマップを実行する前に、単純に条件チェックを行うことができます

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

現在では、.mapは2つの異なる方法で実行できますが、次のような条件付きチェックが必要です。

戻り値のある.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>
 ))
}

上記の機能は両方とも同じです

1
Hemadri Dasari