T
TanStack7mo ago
passive-yellow

Error in development but not in production using Next.js 15

When I trigger the onChange in the select it gives this error:
Cannot update a component (`Router`) while rendering a different component (`ClientComponent`). To locate the bad setState() call inside ``ClientComponent`, follow the stack trace as described in https://react.dev/link/setstate-in-render
Cannot update a component (`Router`) while rendering a different component (`ClientComponent`). To locate the bad setState() call inside ``ClientComponent`, follow the stack trace as described in https://react.dev/link/setstate-in-render
// ServerComponent.tsx
import { getQueryClient } from "@/lib/utils/get-query-client";
import { dehydrate, HydrationBoundary } from "@tanstack/react-query";
export default function ServerComponent() {
const queryClient = getQueryClient();

queryClient.prefetchQuery({
queryKey: ["query1", 4],
queryFn: () => getProduct(4),
});

return (
<HydrationBoundary state={dehydrate(queryClient)}>
<ProductTable />
</HydrationBoundary>
);
}

// ClientComponent.tsx
"use client";
import { useSuspenseQuery } from "@tanstack/react-query";
export function ClientComponent {
const [selectedProductId, setSelectedProductId] = useState<number>(4);

const { data = [], isLoading } = useSuspenseQuery<Product[]>({
queryKey: ["query1", selectedProductId],
queryFn: () => getProduct(selectedProductId),
staleTime: 60 * 1000,
});

return (
<Select
onChange={(value) => setSelectedProductId(Number(value))}
/>
);
}

// database.ts
export async function getProducts(productId: number): Promise<Product[]> {
const pool = await sql.connect(config);
const request = pool.request().input("productId", sql.Int, productId);

const result = await request.query<Product>(`
// sql here
`);

return result.recordset;
}
// ServerComponent.tsx
import { getQueryClient } from "@/lib/utils/get-query-client";
import { dehydrate, HydrationBoundary } from "@tanstack/react-query";
export default function ServerComponent() {
const queryClient = getQueryClient();

queryClient.prefetchQuery({
queryKey: ["query1", 4],
queryFn: () => getProduct(4),
});

return (
<HydrationBoundary state={dehydrate(queryClient)}>
<ProductTable />
</HydrationBoundary>
);
}

// ClientComponent.tsx
"use client";
import { useSuspenseQuery } from "@tanstack/react-query";
export function ClientComponent {
const [selectedProductId, setSelectedProductId] = useState<number>(4);

const { data = [], isLoading } = useSuspenseQuery<Product[]>({
queryKey: ["query1", selectedProductId],
queryFn: () => getProduct(selectedProductId),
staleTime: 60 * 1000,
});

return (
<Select
onChange={(value) => setSelectedProductId(Number(value))}
/>
);
}

// database.ts
export async function getProducts(productId: number): Promise<Product[]> {
const pool = await sql.connect(config);
const request = pool.request().input("productId", sql.Int, productId);

const result = await request.query<Product>(`
// sql here
`);

return result.recordset;
}
If I call it from an api it doesn't have any problems. I'm trying to avoid doing that though as it's not really required in this case.
2 Replies
exotic-emerald
exotic-emerald7mo ago
I am getting the same issue @Determinism Did you find why this is happening?
passive-yellow
passive-yellowOP7mo ago
if I remember correctly it was because I didn't have "use server" at the top of database.ts @$golddy

Did you find this page helpful?