Is making the DataTable a HOC a good idea? - Table is noticeably slow on row selection
interface DataTableContextValue<TData> {
table: Table<TData>;
}
const DataTableContext = createContext<DataTableContextValue<any> | null>(null);
export const useDataTable = <TData,>() => {
const context = useContext(DataTableContext);
if (!context) {
throw new Error(`useDataTable must be used within a DataTableProvider`);
}
return context as DataTableContextValue<TData>;
};
type Props<TData> = {
options: Omit<TableOptions<TData>, "getCoreRowModel">;
children: React.ReactNode | ((table: Table<TData>) => React.ReactNode);
};
export const DataTableProvider = <TData,>({
children,
options,
}: Props<TData>) => {
const [rowSelection, setRowSelection] = useState({});
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
const table = useReactTable({
...options,
_features: [MarkRowFeature, SortableFeature, GenericFeature],
filterFns: {},
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
onColumnFiltersChange: setColumnFilters,
getFilteredRowModel: getFilteredRowModel(), // Client-side filtering
onRowSelectionChange: setRowSelection,
defaultColumn: {
minSize: 0,
size: Number.MAX_SAFE_INTEGER,
maxSize: Number.MAX_SAFE_INTEGER,
},
columnResizeMode: "onChange",
state: {
...options.state,
rowSelection,
columnFilters,
},
});
const updatePageSelections = useCallback(() => {
const pageIndex = table.getState().pagination.pageIndex;
const selectedPageRows = Object.keys(
table.getSelectedRowModel().rowsById,
).reduce(
(acc, id) => ({ ...acc, [id]: true }),
{} as Record<string, boolean>,
);
table.setPageIndexdSelections(pageIndex, selectedPageRows);
}, [table]);
useEffect(() => {
updatePageSelections();
}, [updatePageSelections, rowSelection, table.getState().pagination]);
const contextValue = useMemo(() => ({ table }), [table]);
return (
<DataTableContext.Provider value={contextValue}>
{typeof children === "function" ? children(table) : children}
</DataTableContext.Provider>
);
};
interface DataTableContextValue<TData> {
table: Table<TData>;
}
const DataTableContext = createContext<DataTableContextValue<any> | null>(null);
export const useDataTable = <TData,>() => {
const context = useContext(DataTableContext);
if (!context) {
throw new Error(`useDataTable must be used within a DataTableProvider`);
}
return context as DataTableContextValue<TData>;
};
type Props<TData> = {
options: Omit<TableOptions<TData>, "getCoreRowModel">;
children: React.ReactNode | ((table: Table<TData>) => React.ReactNode);
};
export const DataTableProvider = <TData,>({
children,
options,
}: Props<TData>) => {
const [rowSelection, setRowSelection] = useState({});
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
const table = useReactTable({
...options,
_features: [MarkRowFeature, SortableFeature, GenericFeature],
filterFns: {},
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
onColumnFiltersChange: setColumnFilters,
getFilteredRowModel: getFilteredRowModel(), // Client-side filtering
onRowSelectionChange: setRowSelection,
defaultColumn: {
minSize: 0,
size: Number.MAX_SAFE_INTEGER,
maxSize: Number.MAX_SAFE_INTEGER,
},
columnResizeMode: "onChange",
state: {
...options.state,
rowSelection,
columnFilters,
},
});
const updatePageSelections = useCallback(() => {
const pageIndex = table.getState().pagination.pageIndex;
const selectedPageRows = Object.keys(
table.getSelectedRowModel().rowsById,
).reduce(
(acc, id) => ({ ...acc, [id]: true }),
{} as Record<string, boolean>,
);
table.setPageIndexdSelections(pageIndex, selectedPageRows);
}, [table]);
useEffect(() => {
updatePageSelections();
}, [updatePageSelections, rowSelection, table.getState().pagination]);
const contextValue = useMemo(() => ({ table }), [table]);
return (
<DataTableContext.Provider value={contextValue}>
{typeof children === "function" ? children(table) : children}
</DataTableContext.Provider>
);
};
0 Replies