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のほうが楽に感じます。