How to show loaders when using router.push()
Unanswered
Brown bear posted this in #help-forum
Brown bearOP
I have a server component for showing a list of products it is using searchParams, I have a filter component which is using router.replace(
both the FiltersSection and the ProductsSection are server component and are fetching the same data from the api which is wrapped in react cache()
Here is some minimal code
This is the ProductsSection
I don't get it why I don't see the fallback
pathname?searchParams
), on the server component I am doing data fetching to a third party not to my next server so it takes about 2 seconds to get a response, during this time I want to show a loader but it is not working neither the loader.tsx in page lever not the suspense fallbackboth the FiltersSection and the ProductsSection are server component and are fetching the same data from the api which is wrapped in react cache()
Here is some minimal code
export async function Products({ searchParams }) {
const { page, orderBy, ...searchFilters } = await searchParams;
return (
<section className="py-10 lg:py-20" id="product-listing">
<div className="flex gap-6 flex-col lg:flex-row">
<div className="w-full lg:w-1/4 flex-shrink-0">
<FiltersSection
page={page || 1}
searchFilters={searchFilters}
orderBy={orderBy}
/>
</div>
<div className="w-full lg:w-3/4">
<Suspense fallback={<div>Loading...</div>}>
<ProductsSection
page={page || 1}
searchFilters={searchFilters}
orderBy={orderBy}
/>
</Suspense>
</div>
</div>
</section>
);
}
This is the ProductsSection
export async function ProductsSection({
page,
searchFilters,
orderBy,
}: {
page: number | null;
categoryId: string | undefined;
searchFilters: Record<string, string> | undefined;
orderBy: string | undefined;
locale: string;
}) {
const { products } = await getProducts(
page,
searchFilters,
orderBy
);
return products.map(async (product) => {
return <ProductCard key={product.id} {...product} />;
});
}
I don't get it why I don't see the fallback
1 Reply
Siberian Flycatcher
You need to re-trigger the render of the
Suspense
by providing a unique key every time your filters changeexport async function Products({ searchParams }) {
const { page, orderBy, ...searchFilters } = await searchParams;
return (
<section className="py-10 lg:py-20" id="product-listing">
<div className="flex gap-6 flex-col lg:flex-row">
<div className="w-full lg:w-1/4 flex-shrink-0">
<FiltersSection
page={page || 1}
searchFilters={searchFilters}
orderBy={orderBy}
/>
</div>
<div className="w-full lg:w-3/4">
<Suspense key={JSON.stringify(searchFilters)} fallback={<div>Loading...</div>}>
<ProductsSection
page={page || 1}
searchFilters={searchFilters}
orderBy={orderBy}
/>
</Suspense>
</div>
</div>
</section>
);
}