推荐: JSX 中用 .map
渲染
/**
* Each child in a list should have a unique "key" prop.
* 列表中的每个子元素都必需一个唯一的key属性值
* key 是 React 查看元素是否改变的一个唯一标识 key必须在「兄弟」节点中唯一,确定的。
* 一个 table 中,两次 map 循环时,相互之间的 key 不用唯一,这里的兄弟节点是只一次 map 循环出来的东西之间的唯一
*/
/**
* 不建议使用 index 做为 key 值(禁止)
* 建立在列表顺序改变、元素增删的情况下
*
* 列表项增删或顺序改变了,index 的对应项就会改变
* key 对应的项还是之前列表情况的对应元素的值
* 导致状态 (arr) 混乱,查找元素性能就会变差
*
* 好的做法:
* 如果列表是静态不可操作的,可以选择 index 作为key,但也不推荐
* 很有可能这个列表在以后维护扩展的时候,有可能变更为可操作的列表
*
* 1. 尽量避免使用 index
* 2. 可以用数据的ID(但有可能ID会变动)
* 3. 最好使用动态生成一个静态ID nanoid
*/
// 前提: npm install nanoid
import { nanoid } from 'nanoid'
class App extends React.Component {
state = {
arr: [
{
id: 1,
name: 'Lance'
},
{
id: 2,
name: 'Sherry'
},
{
id: 3,
name: 'Jerry'
}
]
}
render() {
const { arr } = this.state
return (
<table border="1">
<thead>
<tr>
<th>KEY</th>
<th>ID</th>
<th>NAME</th>
</tr>
</thead>
<tbody>
{
arr.map(v => {
const key = nanoid()
return (
<tr key={ key }>
<td>{ key }</td>
<td>{ v.id }</td>
<td>{ v.name }</td>
</tr>
)
})
}
{/* 上下两次 map , 相互之间的 key 不用唯一 */}
{
arr.map(v => {
const key = nanoid()
return (
<tr key={ key }>
<td>{ key }</td>
<td>{ v.id }</td>
<td>{ v.name }</td>
</tr>
)
})
}
</tbody>
</table>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
)
.map
遍历时,显式的传递给元素或组件.map
多层嵌套时,推荐每层 .map
中遍历的元素都单独形成一个组件import { nanoid } from 'nanoid'
class ItemTitle extends React.Component {
render() {
return (
<thead>
<tr>
<th>KEY</th>
<th>ID</th>
<th>NAME</th>
</tr>
</thead>
)
}
}
class ListItem extends React.Component {
render() {
const { sid, item } = this.props
return (
<tr>
<td>{ sid }</td>
<td>{ item.id }</td>
<td>{ item.name }</td>
</tr>
)
}
}
class App extends React.Component {
state = {
arr: [
{
id: 1,
name: 'Lance'
},
{
id: 2,
name: 'Sherry'
},
{
id: 3,
name: 'Jerry'
}
]
}
render() {
return (
<table border="1">
<ItemTitle />
<tbody>
{
this.state.arr.map(v => {
const sid = nanoid()
/**
* key 是不会作为属性传递给子组件的,必须显式传递 key 值
* 目的: 防止开发者在逻辑中对 key 进行操作
*/
return (
<ListItem key={ sid } sid={ sid } item={ v } />
)
})
}
</tbody>
</table>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
)