我正在尝试创建包含一个长列表(约 500 个项目)的 React 组件,每个项目旁边都有复选框。它应该切换每个项目的检查状态并切换列表中所有项目的检查状态。据我所知,我实现了该组件。但我的解决方案性能较低,并且在切换复选框时存在一些时间滞后。当我将其集成到页面中时,它的工作速度比这个 jsFiddle 示例慢。
我做错了什么?我应该选择其他方式来处理项目数据吗?
var Hello = React.createClass({
getInitialState: function () {
var db = [];
for (var i = 0, l = 100; i < l; i++) {
db.push({
name: Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5),
value: i
});
}
return {
db: db
};
},
checkAll: function (ev) {
var items = this.state.db.slice();
items.forEach(function (v) {
v.checked = ev.target.checked;
});
this.setState({db: items});
},
handleCheck: function (ev) {
debugger;
var id = ev.target.dataset.id;
var items = this.state.db.slice();
var item = items.filter(function (v) {
return v.value == id;
})[0];
item.checked = ev.target.checked;
console.log(items.filter(function (v) {
return v.checked;
}));
this.state({db: items});
},
render: function () {
return <div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Value</th>
<th>
<input type="checkbox" onChange={this.handleCheck} id="check-all"/>
<label htmlFor="check-all">Check all</label>
</th>
</tr>
</thead>
<tbody> {
this.state.db.map(function (v, i) {
return (
<tr key={i}>
<td>{v.name}</td>
<td>{v.value}</td>
<td>
<input id={'item-'+i} type="checkbox"
data-id={i}
onChange={this.handleCheck}
checked={v.checked}/>
<label htmlFor={'item-'+i}>Check this</label>
</td>
</tr>
);
}.bind(this))
}
</tbody>
</table>
</div>;
}
});
解决方案
我的表格中有许多具有复杂层次结构的单元格。当我切换复选框值时,所有单元格都会重新渲染,包括那些值未更改的单元格,这会导致巨大的时间延迟。我使用 shouldComponentUpdate
回调将组件拆分为一些小组件,效果很好。感谢大家的帮助!
最佳答案
我对您的代码做了一些改进:https://jsfiddle.net/Lfbodh90/1/
我改变了什么:
在事件处理程序中,您可以通过索引获取项目,从而大大加快查找时间:
handleCheck: function (id) {
var items = this.state.db;
var item = items[id]
item.checked = ev.target.checked;
this.setState({db: items});
}
另一件事:创建复选框时,可以直接传递索引参数,使用bind
:
<input id={'item-'+i} type="checkbox"
onChange={this.handleCheck.bind(this, i)}
checked={v.checked}/>
<label htmlFor={'item-'+i}>Check this</label>
我还删除了给定示例中不需要的 slice
调用。
我增加了上面 JSFiddle 上的项目数量只是为了测试。现在,当您选中/取消选中特定复选框时,速度非常快。
希望这有帮助
关于javascript - ReactJS 可检查列表问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32199366/