Asa*_*saf 12 reactjs react-virtualized
我正在尝试创建一个8列的表,每列包含一个<input />元素。由于某些原因,我在文本输入的on change事件中遇到了延迟。将列数减少到4以下可改善体验。这可能是有道理的,但是我也尝试增加列的数量,结果发现对于10个或更多的列,体验还是很棒的。您可以检查我的超级简单React应用程序,在其中可以动态更改列数-http://com.react.table-with-inputs.s3-website.eu-central-1.amazonaws.com/。
这是我的代码:
import React from 'react';
import { AutoSizer, Table, Column } from 'react-virtualized';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
numOfCols: '8',
};
}
rowGetter = ({ index }) => {
return { index };
};
renderHeaderCell = ({ label }) => {
return (
<span>{label}</span>
);
};
renderCell = ({ rowIndex, columnIndex }) => {
return (
<input key={`input-${rowIndex}-${columnIndex}`} />
);
};
render() {
return (
<div style={{ display: 'flex', flex: 1, flexDirection: 'column', padding: '10px' }}>
<span>NUMBER OF COLUMNS</span>
<input
value={this.state.numOfCols}
onChange={e => this.setState({ numOfCols: e.target.value })}
/>
<br />
<br />
<AutoSizer style={{ flex: 1 }}>
{({ height, width }) => (
<Table
width={width}
height={height}
estimatedRowSize={36}
overscanRowCount={10}
headerHeight={30}
rowHeight={36}
rowCount={20}
rowGetter={this.rowGetter}
>
{
(() => {
const cols = [];
for (let i = 0; i < parseInt(this.state.numOfCols); i += 1) {
cols.push(
<Column
label={`Title${i + 1}`}
dataKey={`title${i + 1}`}
width={120}
cellRenderer={this.renderCell}
headerRenderer={this.renderHeaderCell}
/>
)
}
return cols;
})()
}
</Table>
)}
</AutoSizer>
</div>
);
}
}
export default App;
Run Code Online (Sandbox Code Playgroud)
编辑1:这仅在Chrome(Mac和Windows,台式机和移动设备)上发生。它不会在Safari或Firefox(非桌面版和移动版)上复制。
编辑2:我试图删除AutoSizer但没有任何更改。上载了可以渲染或不显示Tablewith AutoSizer容器的更新版本(http://com.react.table-with-inputs.s3-website.eu-central-1.amazonaws.com/)。
我没有重现这个问题,但是我在您的代码中看到了多个点,这些点可能会在该代码中产生性能问题,所以这是我的尝试。
首先,您是否尝试过减少渲染次数?
例如,也许您的组件可以切换到 PureComponent,以便仅在状态和属性更改时重新渲染。这可以提高性能。您将需要进行广泛的测试,因为您需要检查子组件是否需要重新渲染。
删除内联样式,因为这每次都会创建一个新对象,从而破坏了 React 可以进行的所有渲染优化。如果您仍然需要 style={something} ,那么请移至something类声明之外的 const 变量,以确保一次性创建该对象。请注意,这是一种不好的做法,因此请检查代码中出现的所有其他情况。
就在那里,我至少看到两个地方 React 将重新渲染一个元素,但该元素没有改变,因为对象内容是硬编码的。
为什么要创建一个新函数然后像这样内联执行它?
更有效的方法是使用 lodash 的地图:
map(range(this.state.numOfCols), i => (<Column
label={`Title${i + 1}`}
dataKey={`title${i + 1}`}
width={120}
cellRenderer={this.renderCell}
headerRenderer={this.renderHeaderCell}
/>))
Run Code Online (Sandbox Code Playgroud)
解决所有明显的问题后,安装一个性能包,例如https://github.com/welldone-software/why-did-you-render并检查为什么您的 App 组件渲染过多。
也许您的示例中未包含的某些代码导致组件每次都重新渲染?
编辑:重新阅读代码后,我 75% 确定问题出在 style={{ flex: 1 }} 导致完全 AutoSizer 重新渲染!
| 归档时间: |
|
| 查看次数: |
234 次 |
| 最近记录: |