【发布时间】:2019-12-06 08:55:31
【问题描述】:
编辑:这是一个工作示例:https://codesandbox.io/s/gracious-silence-5n4pv 为什么按下按钮会重新渲染所有单元格,但滚动不?
我正在尝试提高性能,因此我将一个组件提取到具有更简单的道具的东西中 React.memo 友好:
interface DataTableCellProps {
header: string;
value: string;
isRepeatedValue: boolean;
width: number;
}
const DataCell = styled.div<{ width: number; isRepeatedValue: boolean }>`
padding-left: 0.5rem;
padding-right: 0.5rem;
width: ${props => props.width}px;
color: ${props => (props.isRepeatedValue ? grey : lightGrey)};
display: flex;
`;
/** Data table cells. A pure component that can be memoised easily (all props are simple types) */
const DataTableCell = React.memo(
(props: DataTableCellProps) => {
console.log("Rendering");
return (
<DataCell
role="cell"
area-header={props.header}
width={props.width}
isRepeatedValue={props.isRepeatedValue}
>
<Tooltip title={props.value} placement="bottom-start" enterDelay={500}>
<span className="text-truncate">{props.value}</span>
</Tooltip>
</DataCell>
);
},
(a, b) => {
console.log("Are props equal?");
return true;
}
);
它只接受字符串、布尔值和数字作为输入。但是我已经添加了一个 cusom isEqual 支票来记录,现在强迫它总是说它是平等的。根据我的理解,它应该始终返回缓存的组件,并且永远不会重新渲染,除非它们改变了键。
这里是它被渲染的地方,去掉了所有不起作用的东西:
const DataTableBody = (props: DataTableBodyProps) => (<FixedSizeList
width={300}
height={300}
itemCount={props.rows.length}
itemSize={35}
outerRef={props.containerRef}
outerElementType={CustomScrollbarsVirtualList}
>
{({ index, style }) => {
const row = props.rows[index];
props.prepareRow(row);
return (
<div
style={{
...style,
transform: `translate(${props.horizontalScroll}px, 0)`,
display: "flex"
}}
>
{row.cells.map((cell: any) => (
<DataTableCell
key={cell.getCellProps().key}
value={cell.value}
header={cell.column.Header}
width={
props.widths[cell.column.Header] ||
props.defaultColumnWidth
}
isRepeatedValue={cell.isRepeatedValue}
/>
))}
</div>
);
}}
</FixedSizeList>);
我记录了密钥(来自react-tables),它是每个单元格唯一的稳定字符串。
当上面示例中的 prop horizontalScroll 发生变化时,这将改变 div 的渲染,但不应该影响 DataTableCell,因为它没有传入 props,并且 key 没有改变 -我将控制台日志Rendering 打印了数百次。我没有收到Are props equal?
但是,它可以很好地滚动组件!垂直滚动时,style 会发生变化,它会重新渲染,我看到一大堆Are props equal?,但只有少数Rendering 日志。我非常有信心正在渲染具有新密钥的密钥,并且正在检查现有密钥是否相等而不是被渲染。
那么为什么它不适用于horizontalScroll?
【问题讨论】:
标签: reactjs