はじめに
概要
Reactでフロントエンドのツールを作っている時に、state
の中に設定されているjson形式のデータを、HTMLのテーブルとして表示する機能を作りました。
その際に、表示の基となるデータを変更しても、テーブル内に表示される値は切り替わらないというエラーに出会ったため、簡単な解決方法をここにメモしておきます。
TL;DR
Reactを使うときに、イテラブルなオブジェクトを基に画面表示をする場合は、各要素ごとにidが振られていないと、同オブジェクトの値が変わっても画面表示が切り変わらないことがあるようです。
やりたかったこと
state
に登録されているjsonの配列形式のデータを、HTMLの<table>
要素の中に上手く表示させることがしたかったです。
具体的には、state
には以下のようなデータが登録をされていました。
this.state.dummyData = [
{
"key":"aa",
"value":"bb"
},{
"key":"aa",
"value":"bb"
},{
"key":"aa",
"value":"bb"
}
]
こんな感じで、単純なオブジェクトの配列になっていました。
これを基に画面表示をする、概略化したコードは、以下のような感じです。
render(){
// 省略
<table>
<tbody>
{this.state.dummyData.map((d,i) =>
<tr>
<td>{d.key}</td>
<td>{d.value}</td>
</tr>
)}
</tbody>
</table>
// 省略
}
配列の中身の数だけ<tr>
を生成して、その中の<td>
に値を表示しているだけです。
しかしこれだと、this.state.dummyData
の値が変わっても、テーブルの中身は変わらない場合がありました。
解決方法
解決方法のヒントは、Reactの開発モードの時に出るコンソール内のwarningにちゃんと出ていました。
Warning: Each child in a list should have a unique "key" prop.
Reactで、リストを基に画面に要素を複数個表示する場合は、各要素にkey
を設定することが推奨されています。そのため、以下のように変更をしました。
まず、表示基のstate
内のオブジェクトの各項目には、idを振るようにしました。
this.state.dummyData = [
{
"id":001,
"key":"aa",
"value":"bb"
},{
"id":002,
"key":"aa",
"value":"bb"
},{
"id":003,
"key":"aa",
"value":"bb"
}
]
そして、画面表示をする際は、<tr>
にkey
としてidを設定します。
render(){
// 省略
<table>
<tbody>
{this.state.dummyData.map((d,i) =>
<tr key={d.id}>
<td>{d.key}</td>
<td>{d.value}</td>
</tr>
)}
</tbody>
</table>
// 省略
}
こうすることで、表示基のオブジェクトが変更されたときに毎回render関数が走るようになり、きちんと画面が切り替わりました。
まとめ
Reactを使うのは初めてだったので、単純なところで引っかかってしまいました。
「React 配列 展開」とかでググって出てくるサンプルコードの多くは、map
関数の中でHTML要素にkey
を設定していなかったのですが、表示内容が変更される可能性がある場合には、きちんとkey
を設定しなければならないようです。