LoginSignup
2
2

More than 3 years have passed since last update.

ReactでsetStateをしても画面表示が切り替わらない問題の解決方法メモ

Last updated at Posted at 2020-07-29

はじめに

概要

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を設定しなければならないようです。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2