这是一个很常见的场景,我们有一个包含大量数据的表。每行都有一个复选框,用于从选定行导出数据。
在 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 不适用于这种情况,因为它依赖于 selection 状态。
我知道我可以在子组件中实现 shouldComponentUpdate,只是想知道是否可以从根目录解决这个问题?
感谢您的任何建议,新年快乐。
更新: 将 parent 变成 React.Component 而不是函数组件可以解决这个问题,因为 setState 不会刷新回调实例。我认为这两种组件几乎相同,但显然它们不同。希望它可以帮助某人,但仍然想知道是否可以将其归档到函数组件中。
答案 0 :(得分:0)
你可以通过多种方式来实现,这里我提到了几种。