It is a quite common scenario, we have a table with huge data. It has a check box for each row which used to exporting data from selected row.
in 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>
);
};
In 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>
);
}
);
Above is the basic code structure. 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 issue. useCallback does not work for this case since it has dependency on the selection state.
I know I can implement shouldComponentUpdate in child component, just wonder if possible to fix the issue from root ?
Appreciate for any suggestions and happy new year.
UPDATE: Turn parent into React.Component instead of function component can solve the issue because setState will not refresh callback instance. I thought those two kinds of components are pretty much same, but apparently they are different. Hope it could help someone, but still wonder if possible to archive this in function component.