我遇到了严重的性能问题。我有一个包含2000个相当大的DOM结构列表项的列表的应用程序,当我在列表组件中更改一个项目时,如下所示:
changeOne:function(){
var permTodos = this.props.todos;
permTodos[Math.floor((Math.random() * 5) + 0)].todo=((Math.random() * 50) + 1);
this.setState({ todos: permTodos });
},
它重新呈现虚拟DOM表示中的所有列表项,这非常慢。在Angular1中完成同样的事情要快40倍。我试图为列表项实现shouldComponentUpdate
shouldComponentUpdate:function(nextProps, nextState){
return this.props.todo!==nextProps.todo;
},
但是this.props.todo与nextProps.todo相同,所以没有任何改变。我已经在这个小提琴https://jsfiddle.net/2Lk1hr6v/29/中重新创建了我的应用程序的迷你版本,我希望有那些可以帮助我处理这种不幸情况的反应专家。
答案 0 :(得分:2)
您需要为列表中的每个项目添加唯一键:
this.state.todos.map(function(todo) {
return <TodoItem key={todo.id} todo={todo} done={this.done} />
}.bind(this))
密钥必须与项目相关联,例如它可能是id
。它必须不是列表中的所有项目所在的索引。
答案 1 :(得分:1)
此处也进行相同编辑,如另一个thread中所述。
另外我注意到我在小提琴中注意到的另外两件事。在TodoItem类中,您必须说this.props.done
而不是this.done
。
render: function() {
return <li onClick={this.props.done}>{this.props.todo}</li>
}
在TodoList类中,您指的是未声明的this.done
。您应该声明该功能吗?。
{
this.state.todos.map(function(todo) {
return <TodoItem todo={todo} done={this.done} />
}.bind(this))
}
同时切换到ES6 arrow functions!你不必在它结束时绑定它。代码更小更清洁!!
{
this.state.todos.map(todo => <TodoItem todo={todo} done={this.done} />)
}
查看编辑过的小提琴:https://jsfiddle.net/2Lk1hr6v/33/
这应该比现在快得多!
PS:探索其他ES6功能here !!