1、在专用组件中渲染列表
这点在渲染大型数据集合的时候尤为重要。React在渲染大型数据集合时表现的非常差,因为协调器必须评估每个变化的集合所产生的组件。因此,建议使用专门的组件来映射集合(数组)并且渲染这个组件,切不再渲染其他组件:
不好的:
class MyComponent extends Component {
render() {
const {todos, user} = this.props;
return (<div>
{user.name}
<ul>
{todos.map(todo => <TodoView todo={todo} key={todo.id} />)}
</ul>
</div>)
}
}
在上面例子中,当 user.name
改变时,React 会不必要的协调所有的 TodoView 组件. 尽管TodoView组件不会重新渲染,但是协调的过程本身就非常昂贵.
好的:
class MyComponent extends Component {
render() {
const {todos, user} = this.props;
return (<div>
{user.name}
<TodosView todos={todos} />
</div>)
}
}
class TodosView extends Component {
render() {
const {todos} = this.props;
return <ul>
{todos.map(todo => <TodoView todo={todo} key={todo.id} />)}
</ul>)
}
}
尽量不要使用数组的索引作为key
许多的开发人员在渲染列表的时候,会使用项目的索引作为key
比如:
{todos.map((todo, index) =>
<Todo
{...todo}
key={index}
/>
)}
这会导致什么问题呢? 当我们的列表是可变的,比如可以删除,改变位置,因为React diff算法依赖于key 当我们修改了位置后 触发render 那么我们的key 此时的数组索引可能就混乱了
最好:
{todos.map((todo) =>
<Todo {...todo}
key={todo.id} />
)}
当然id应该是唯一值,或者使用 shortid 来生成id,但是很多的情况下 我们的 todo 并没有id或者其他肯定是唯一的字段,我们也懒得去生成shortid,我们就是想简简单单的渲染一个不变的列表而已,那么就涉及到一些可以使用 index 作为 key的条件:
- 1、列表和项目是静态的,它们不是计算的,也不会改变.
- 2、列表中的项目没有id;
- 3、列表永远不会重新排序或过滤。
详细请参考 Index as a key is an anti-pattern