例如,当在表中呈现一长串元素时,对setState
的任何调用,无论它是否更改表用于枚举的数据,都会导致每个子对象的重新呈现。
每次选中/取消选中都会重新渲染每个元素。这会导致2000个元素更加复杂,从而大大降低速度。我将使用虚拟化,但是在执行此操作之前,请确保它具有最佳性能。
class App extends React.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
const rows = Array.from({ length: 200 }, (v, k) => k + 1).map(i => ({
id: i,
field1: "hello",
field2: "cruel",
field3: "world"
}));
this.state = {
selectedIds: [],
rows
};
}
onChange(e) {
const name = e.target.name;
const checked = e.target.checked;
const selectedIds = [...this.state.selectedIds];
if (!checked) {
const index = selectedIds.findIndex(x => x === name);
selectedIds.splice(index, 1);
} else {
selectedIds.push(name);
}
this.setState(state => ({ selectedIds }));
}
render() {
const { rows, selectedIds } = this.state;
return (
<div className="App">
<h5>{selectedIds.length} Rows Selected</h5>
<table>
<thead>
<tr>
<td>Select</td>
</tr>
<tr>
<td>Field 1</td>
</tr>
<tr>
<td>Field 2</td>
</tr>
<tr>
<td>Field 3</td>
</tr>
</thead>
<tbody>
{rows.map(row => {
console.log(row);
return (
<tr key={row.id}>
<td>
<input
type="checkbox"
onChange={this.onChange}
name={row.id}
/>
</td>
<td>
<div>{row.field1}</div>
</td>
<td>
<div>{row.field2}</div>
</td>
<td>
<div>{row.field3}</div>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
}
}
我从其他答案中看到,重新运行render
函数是预期的行为
ReactJS - Does render get called any time "setState" is called?
但是,如果是这样,当该链接中的元素数增加到4000时,为什么单击时会有这么慢的速度?当使用稍微复杂一些的自定义React组件时,如果仅使用200个项目,则会发现速度显着降低。
答案 0 :(得分:1)
要解决此问题,您需要为行项目创建一个附加组件。这样,它将具有单独的呈现功能,并且不会重新呈现自身,因为行组件没有改变,只有表格组件没有改变。
{rows.map(row => {
return (
<RowItem row={row} onChange={this.onChange}>
);
}}
,您的新组件将如下所示:
class RowItem extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<tr key={this.props.row.id}>
<td>
<input
type="checkbox"
onChange={this.props.onChange}
name={this.props.row.id}
/>
</td>
<td>
<div>{this.props.row.field1}</div>
</td>
<td>
<div>{this.props.row.field2}</div>
</td>
<td>
<div>{this.props.row.field3}</div>
</td>
</tr>
);
}
}