None of the above (or anywhere else on the interwebs) worked for me but here's what did. And I imagine, with the number of people who've asked this same question about React Table v7, that in version 8 of React Table, the state, especially state having to do with selection, has been ironed out. But anyway this is the ONLY workaround that worked for me, loosely based on this codesandbox.
// Parent component
I used a useCallback
hook to prevent my setSelectedRows
(your setSelection
) function being passed to the child as a new function and kicking off multiple renders.
And I passed in an initial state that sets React Table's selectedRowIds
with the parent's selectedRows
:
const ParentDoingParentyThings = () => {
const [selectedRows, setSelectedRows] = React.useState({});
const handleSelection = React.useCallback((value) => {
setSelectedRows(value);
}, []);
return (
<Table
data={tableData}
setSelectedRows={handleSelection}
initialState={{ sortBy: [{ id: 'totalSeries', desc: true }], selectedRowIds: selectedRows }}
...
/>
)
}
// And the Table / child
Then!...
- I use this lesser know function from React Table called
useMountedLayoutEffect
. Dont ask me in detail what it does, but it works, that's what it does....
- Then I pull from RT's
selectedRowIds
state
- And I use RT's
useMountedLayoutEffect
function like I would a useEffect
import {
...
useMountedLayoutEffect,
} from 'react-table';
export const Table = ({
data,
setSelectedRows,
initialState,
...
}: Props) => {
...
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
state: { selectedRowIds },
} = useTable(
{
data: tableData,
initialState,
...
},
useSortBy,
useRowSelect,
);
useMountedLayoutEffect(() => {
setSelectedRows && setSelectedRows(selectedRowIds);
}, [setSelectedRows, selectedRowIds]);
return (
<table {...getTableProps()} className={className}>
...
</table>