这是一个很常见的场景,我们有一个包含大量数据的表。每行都有一个复选框,用于从选定行导出数据。
在 App.tsx 中,
const App = () => {
const [selection, setSelection] = useState<string[]>([]);
const handleSelect = useCallback(
(name: string) => {
if (selection.includes(name)) {
selection.splice(selection.indexOf(name), 1);
setSelection([...selection]);
return;
}
setSelection([...selection, name]);
},
[selection, setSelection]
);
return (
<Paper>
<TableContainer>
<Table stickyHeader aria-label="sticky table">
<TableHead>
...
</TableHead>
<TableBody>
{rows.map((row) => {
return (
<Row
key={row.name}
row={row}
selected={selection.includes(row.name)}
onSelect={handleSelect}
/>
);
})}
</TableBody>
</Table>
</TableContainer>
</Paper>
);
};
在 Row.jsx 中,
export const Row = React.memo(
({ selected, row, onSelect }: RowProps) => {
const handleSelect = () => {
onSelect(row.name);
};
return (
<TableRow key={row.code}>
<TableCell key="checkbox">
<Checkbox checked={selected} onChange={handleSelect} />
</TableCell>
// render other columns ...
</TableRow>
);
}
);
以上是基本的代码结构。My problem is that when a row is selected/deselected, the app will be re-rendered since the state refreshed, that will cause callback instance refreshed as well, then all child Row will be re-rendered which I want to avoid because of performance问题。useCallback不适用于这种情况,因为它依赖于选择状态。
我知道我可以在子组件中实现shouldComponentUpdate,只是想知道是否可以从 root 解决问题?
感谢任何建议和新年快乐。
更新:将 parent 变成 React.Component 而不是函数组件可以解决问题,因为 setState 不会刷新回调实例。我认为这两种组件几乎相同,但显然它们是不同的。希望它可以帮助某人,但仍然想知道是否可以将其存档在功能组件中。