Reactのリストコンポーネントのkeyにindexを使ってはいけない
React始めて1か月たった。 調べものをしていると、サンプルコードでlistコンポーネントのkeyにindexを使っているものがたまに見かけられる。 こんなの
render() { const list = this.props.usernames.map((username,index) => { return <li key={index}>username</li> }); return ( <ul>{list}</ul> ); }
...不変なリストであればこれで問題ないのかもしれないが、 リストの中身を変更したときにdomを差分更新することができないらしい。
例えばリストの中に入力エリアがある場合、入力内容はリストの変更に追随しない。
import React, { Component } from 'react'; class InputArea extends Component { render() { return ( <div className="form-group row"> <label className="col-sm-2 col-form-label">{this.props.label}</label> <div class="col-sm-10"> <input type="text" className="form-control" /> </div> </div> ) }; } class Question extends Component { constructor(props) { super(props); this.state = { questions: [ { id: 1525018854, label: 'do you like apple?' }, { id: 1525018844, label: 'do you like banana?' }, { id: 1525018824, label: 'do you like orange?' }, ] } } add = () => { const question = { id: +new Date, label: this.refQuestion.value }; this.setState({ questions: [question].concat(this.state.questions) }); }; render() { const questionList = this.state.questions.map((question, index) => { return <InputArea key={index} label={question.label} /> }); return ( <div> {questionList} <div className="form-group"> <textarea className="form-control" placeholder='question?' ref={(elm) => { this.refQuestion = elm; }} /> <button className="btn btn-primary" onClick={this.add}>add</button> </div> </div> ) } }
Eslint使ってなければ気付かなかったと思う。