if data is empty array, then rendering table is causing infinite rerenders
TanStack Table version
10.7.0
Framework/Library version
19.0.0
Describe the bug and the steps to reproduce it
in below code, data is being fetch through an api, and meanwhile it is being fetched an empty array is passed to useReactTable, and in this case its causing inifinite rerenders and some time freezing the app..
PS: below code is fixed by condtional rendering by checking if data is not empty, try similar code with removing the check or passing empty array..
please handle empty array edge case, i can understand that columns configuration depends on data but this is something developer would face difficulties finding the problem as we know infinite rerending issue is something little difficult to debug
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
NA
Screenshots or Videos (Optional)
import { useNavigate, useParams } from "react-router-dom"; import { TABS_ASSESSMENTS } from "./constants"; import { useAssessmentData } from "./useAssessmentData"; import { getCoreRowModel, getSortedRowModel, SortingState, useReactTable, } from "@tanstack/react-table"; import { useAssessmentColumns } from "./useAssessmentColumns"; import { useState } from "react"; import { useAssessmentActionColumns } from "./useAssessmentActionColumns"; import { useTypedNavigate, PageHeader, Tabs, TableV2, IPartnerAssessmentCatalogueItem, useAuth, useGetAllPartnersAssessmentActionsQuery, IPartnerAction, Spinner, } from "@regahead/common";
export type AssessmentTabs = | "actions" | "all" | "assigned" | "inProgress" | "completed"; export const PageAssessment = () => { const { org } = useAuth(); const navigate = useNavigate(); const typedNavigate = useTypedNavigate();
const [sorting, setSorting] = useState<SortingState>([]);
const [selectedAssessment, setSelectedAssessment] = useState<number[]>([]); const { data, isLoading: assessmentLoading } = useAssessmentData(); const { activeTab = "all" } = useParams<{ activeTab?: AssessmentTabs; }>();
const columns = useAssessmentColumns( activeTab as Exclude<AssessmentTabs, "actions">, selectedAssessment, data, setSelectedAssessment );
const table = useReactTable<IPartnerAssessmentCatalogueItem>({ data: data[activeTab].data as any[], columns, state: { sorting, }, onSortingChange: setSorting, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), });
const { data: actionData, isLoading } = useGetAllPartnersAssessmentActionsQuery(org!.id); const actionColumns = useAssessmentActionColumns(actionData ?? []); const actiontable = useReactTable<IPartnerAction>({ data: actionData ?? [], columns: actionColumns, state: { sorting, }, onSortingChange: setSorting, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), });
const handleTabNavigation = (tabId: string) => {
navigate(/assessments/${tabId as typeof activeTab});
};
if (isLoading || assessmentLoading) { return ( <div className="w-full flex items-center justify-center py-56"> <Spinner /> ); }
return (
Do you intend to try to help solve this bug with your own PR?
None
Terms & Code of Conduct
- [x] I agree to follow this project's Code of Conduct
- [x] I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
Instead of writing this:
function Component() {
useReactTable({
data: actionData ?? [],
})
}
...write this:
const EMPTY_ARRAY = [] as const;
function Component() {
useReactTable({
data: actionData ?? EMPTY_ARRAY,
})
}
The problem is that when you fallback on [] directly, it creates a new array on every render.