Infinite re-render when using useQuery()
select
and useReactTable()
#8838
-
Hi! I'm building a simple table:
However I ran into a problem when I:
My hypothesis is:
However, one surprising observation is that if I change This breaks my hypothesis above and I can't explain why one causes infinite re-render and one doesn't. Does anyone have an idea why? import { useQuery } from "@tanstack/react-query";
import { getCoreRowModel, useReactTable } from "@tanstack/react-table";
import { useState } from "react";
const columns = [
{
id: "name",
accessorKey: "name",
},
{
id: "date",
accessorKey: "date",
},
];
const emptyData: any[] = [];
export default function App() {
console.log("---render");
const [count, setCount] = useState(0);
const query = useQuery({
queryKey: ["test"],
queryFn: async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return [];
},
select: () => {
return [
{
name: "hello",
// this causes infinite re-render
date: new Date("2025-03-19"),
// // this doesn't cause infinite re-render
// date: new Date("2025-03-19").getTime(),
},
];
},
});
const table = useReactTable({
data: query.data ?? emptyData,
columns,
getCoreRowModel: getCoreRowModel(),
});
if (query.isLoading) {
return <div>Loading...</div>;
}
if (query.isError) {
return <div>Error</div>;
}
return (
<div>
<button onClick={() => setCount((prev) => prev + 1)}>
increase count
</button>
{table.getRowModel().rows.map((row) => (
<div key={row.id}>{JSON.stringify(row.original.date)}</div>
))}
</div>
);
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
we perform structural sharing on the result of the queryFn and the result of select. So even if select runs on every render, we keep the references stable if nothing changed. Dates can’t be compared though, so it will yield a new reference. You’d need to memoize select with
|
Beta Was this translation helpful? Give feedback.
we perform structural sharing on the result of the queryFn and the result of select. So even if select runs on every render, we keep the references stable if nothing changed. Dates can’t be compared though, so it will yield a new reference. You’d need to memoize select with
useCallback
for that..getTime()
returns a primitive so it’ll work again. structural sharing is turned on per default, but only works for json serializable things.