我使用Array.map在React中渲染多个项目时遇到了奇怪的症状。 在下面的代码中,filtered1和filtered2应该显示相同的结果。但是,结果不同。
似乎Array.map重用了React组件的实例。 这是Array.map的正确行为吗?
您可以看到完整的来源和演示here。
class Row extends React.Component {
constructor(props) {
super(props)
this.state = {
id: props.data.Id,
isTrue: props.data.IsTrue
}
}
render () {
const {data} = this.props
return (
<tr>
<td>{data.Id}</td>
<td>{data.IsTrue ? 'true' : 'false'}</td>
<td style={{backgroundColor:(this.state.isTrue ? 'green' : 'red')}}>{this.state.id}</td>
<td style={{backgroundColor:(this.props.data.IsTrue ? 'green' : 'red')}}>{this.props.data.Id}</td>
</tr>
)
}
}
class App extends React.Component {
constructor(props) {
super(props)
this.state = { filter: 'all' }
}
render () {
const data = [
{"Id":"1","IsTrue":true},{"Id":"2","IsTrue":true},{"Id":"3","IsTrue":false},{"Id":"4","IsTrue":false},{"Id":"5","IsTrue":true},
{"Id":"6","IsTrue":true},{"Id":"7","IsTrue":false},{"Id":"8","IsTrue":true},{"Id":"9","IsTrue":true},{"Id":"10","IsTrue":false}]
const filtered1 =
data
.filter(x => this.state.filter == 'all' || x.IsTrue)
.map((item, index) => (<Row key={index} data={item} />))
const filtered2 =
data
.map((item, index) => (<Row key={index} data={item} />))
.filter(x => this.state.filter == 'all' || x.props.data.IsTrue)
return (
<div>
<select value={this.state.filter} onChange={e => this.setState({filter: e.target.value})}>
<option value='all'>All</option>
<option value='ts'>Trues</option>
</select>
<div>
<span>
<h1>filter -> map</h1>
<table>
<thead>
<tr>
<th>Id</th>
<th>IsTrue</th>
<th>State Value</th>
<th>Props Value</th>
</tr>
</thead>
<tbody>
{filtered1}
</tbody>
</table>
</span>
<span>
<h1>map -> filter</h1>
<table>
<thead>
<tr>
<th>Id</th>
<th>IsTrue</th>
<th>State Value</th>
<th>Props Value</th>
</tr>
</thead>
<tbody>
{filtered2}
</tbody>
</table>
</span>
</div>
</div>
)
}
}
答案 0 :(得分:2)
不要使用数组的索引作为键;使用有关item
的一些独特信息,例如:
key={`${item.Id}:${item.IsTrue}`}
通过使用数组的索引,React认为项目是相同的,即使它们是不同的。 React不会查看项目内部,它只查看键值。如果键是相同的,它会重用&#34; old&#34;组件无需重新渲染。
如需进一步阅读,请参阅Lists and Keys的文档。您会注意到他们没有使用索引作为关键字,除非在一个场景中,他们明确警告:
仅在项目没有稳定ID时执行此操作