ReactでHTMLをレンダリングしているとWarningがでることがあります。

警告なので放置していても動作しますが、パフォーマンスなどに影響がでる可能性があるのでできれば修正したい。

今回はループ処理などででる、keyを取り上げます。

keyの警告

Warning: Each child in a list should have a unique "key" prop.
Check the render method of `List`. See https://fb.me/react-warning-keys for more information.

こんな感じ警告が出ることがあります。

直訳すると「リスト内の要素にはユニークなキーを付けろ」って感じです。

なんのこっちゃ、htmlのliにはkeyなんて属性ありませんが…

コード

const listData = ['1st','2nd','3rd'];
class App extends Component {
  render() {
    return(
      <List data={listData} />
    );
  }
}

const List = (props) => {
  const listItems = props.data.map((text,index)=>{
    return <li>{text}</li>
  });

  return (
    <ul>{listItems}</ul>
  );
}

上記が警告がでたコードです。

ただ配列をループしてliで表示しているだけです。

keyは重要らしい

ReactがVirtualDOMのdiffからDOMに反映させるときにこのkeyを利用して最小限の変更にするようです。

keyの値や順序などを比べて反映させるんでしょうね。

別にliの値(innerText)でもいいじゃんと思いますが、ユニークではない可能性があります。

ユニークなキーを付けろって警告なのでkeyには一意の値を付ける必要があります。

DBデータの場合

id text
1 1st
2 2nd
3 3rd

DBのデータなら通常レコード毎にidなど一意の値を保持していると思います。

それをkeyとして渡せばいいみたいです。

修正コード

const listData = [{id:1,text:'1st'},{id:2,text:'2nd'},{id:3,text:'3rd'}];//DBからのレコード結果的な
class App extends Component {
  render() {
    return(
      <List data={listData} />
    );
  }
}

const List = (props) => {
  const listItems = props.data.map((res)=>{
    return <li key={res.id}>{res.text}</li>
  });

  return (
    <ul>{listItems}</ul>
  );
}

ユニークなキーが無い

csvからのデータなど、ユニークなキーが無い場合はどうするのか??

その場合は配列のindexを利用しましょう。

修正コード

const listData = ['1st','2nd','3rd'];
class App extends Component {
  render() {
    return(
      <List data={listData} />
    );
  }
}

const List = (props) => {
  const listItems = props.data.map((text,index)=>{
    return <li key={index}>{text}</li>
  });
  return (
    <ul>{listItems}</ul>
  );
}

mapは第2引数でindexを取得できます。

0から始まるので1stは0、2ndは1のindexになります。

どうしてもユニークなキーが無い場合はindexを利用しましょう。

まとめ

keyを指定すればReactが最小限の差分で更新してくれるようなので、パフォーマンス向上につながることでしょう。

Reactはいろいろお作法が多くて結構大変だな…

慣れれば使いやすいはずですが、まだjQueryのほうが楽に感じます。