如何解决如何避免所有子组件重新渲染而不覆盖子组件中的 shouldComponentUpdate
这是一个很常见的场景,我们有一个包含大量数据的表。每行都有一个复选框,用于从选定行导出数据。
在 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 不会刷新回调实例。我认为这两种组件几乎相同,但显然它们不同。希望它可以帮助某人,但仍然想知道是否可以将其归档到函数组件中。
解决方法
你可以通过多种方式来实现,这里我提到了几种。
- 您可以将带有自定义实现的 arePropsEqual 函数传递给子组件中的 React.memo 函数。
- 目前您正在将一个对象(行)传递给子组件。而不是传递对象分别传递每个单独的道具。组件在渲染组件之前会进行浅层比较。如果你传递一个对象浅比较总是返回 props 不相等,这就是它重新渲染的原因。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。