Reactで配列ループの利用方法をおさらいするため、Reactのドキュメント Lists and Keys - React を読みつつ調べたことをまとめようと思います。
サンプルコード
6色の色を配列で定義し、それをReactで table
としてレンダリングする簡単なサンプルを作りました。
See the Pen ColorTable by Masayuki Goto (@gotchane) on CodePen.
コードも貼っておきます。
const colors = ['Red','Orange','Yellow','Green','Blue','Violet'];
class ColorTable extends React.Component {
renderTable() {
const rows = colors.map((color,index) =>
<tr key={color}>
<td>
{index + 1}
</td>
<td>{color}</td>
</tr>
);
return (
<table border='1' cellSpacing='0'>
<thead>
<tr>
<th>Number</th>
<th>Name</th>
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
)
}
render() {
return (
<div>
{this.renderTable()}
</div>
)
}
};
class App extends React.Component {
render() {
return (
<div>
<h2>ColorTable</h2>
<ColorTable />
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
配列ループ利用時のポイント
配列ループにはArray.prototype.map()を使う
Reactのドキュメントにもあるように、配列のループには Array.prototype.map()を使います。Array.prototype.map()
は、配列要素全てに対し与えられた関数で処理し、新しい配列を戻り値として返す関数です。
Array.prototype.map()
を使うことで、値に更新があっても、新しく作った配列を再レンダリングすれば良いような形にしているのかなと思います。
配列ループの要素には一意なKeyを指定する
配列ループで要素を作成する際には、 props
に key
を指定します。
これはReactの仮想DOMの差分を反映させる際、最小限のDOM変更にするために利用されます。
const rows = colors.map((color,index) =>
<tr key={color}>
<td>
{index + 1}
</td>
<td>{color}</td>
</tr>
);
もし下記のように、Keyとなる値に重複した値を指定したとします。 Red
を重複させてみました。
const colors = ['Red','Red','Yellow','Green','Blue','Violet'];
すると下記のような警告メッセージが出ます。一意になっていないと要素が重複したり省略されたりして、予期せぬ挙動が起こる可能性があるというメッセージですね。
Warning: Encountered two children with the same key, `Red`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
Reactが各要素を識別できるよう、一意の key
を指定してあげる必要があります。
keyはループ対象要素の一番上の階層に設定する
要素に指定する key
の位置ですが、tr > td
のようにネストした要素の場合は、一番上の階層に key
を設定する必要があります。(ここでかなりハマりました。。)
もし下記のように、 tr
ではなく一つ下の階層の td
に key
を指定したとします。
const rows = colors.map((color,index) =>
<tr>
<td key={color}>
{index + 1}
</td>
<td>{color}</td>
</tr>
);
すると下記のような警告メッセージが出ます。そもそもkey
をReactが認識出来ていないようなメッセージですね。
Warning: Each child in an array or iterator should have a unique 'key' prop.
ul > li
のように、ループする要素がネストしていない場合は考慮しなくて良いと思いますが、複雑な要素をループさせるときには、ループしている要素の一番上の階層に key
を指定することが必要だと思います。