React - 更改一个列表项时出现严重的性能问题

时间:2017-06-16 20:27:43

标签: reactjs

我遇到了严重的性能问题。我有一个包含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/中重新创建了我的应用程序的迷你版本,我希望有那些可以帮助我处理这种不幸情况的反应专家。

2 个答案:

答案 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 !!