api call in page.tsx blocks entire page
Answered
Morelet’s Crocodile posted this in #help-forum
Morelet’s CrocodileOP
Using the app router and making an api call directly in the page component blocks the entire page. The reason the call is in the page is because I would like to pass the loading state to the child components which need the data as well. I also have some static components on the page and would like them to be rendered while the API call finishes. Is this possbile or do I need to use a loading.tsx for the entire page?
export default async function MyEmployees(props: {
searchParams?: Promise<EmployeeParams>;
}) {
const searchParams = await props.searchParams;
const data = await getEmployees(searchParams);
return (
<MainContent>
<PageHeader
title="Employee listing"
description="A list of all active employess in the system"
>
<Refresh />
<Link href="/employees/add" className="p-button">
Add Employee
</Link>
</PageHeader>
<EntitiesFilters />
<EmployeeList data={data} />
</MainContent>
);
}
Answered by Asian black bear
Don't await the promise and pass it down to the list component as a promise.
8 Replies
Asian black bear
Don't await the promise and pass it down to the list component as a promise.
Answer
Asian black bear
Assuming it's a client component you can then
use(thePromise)
it.This will trigger the closest Suspense boundary.
Which can be the
loading.tsx
file or a manual Suspense wrapping the list component.Morelet’s CrocodileOP
Thanks @Asian black bear that worked as suggested by using as
<Suspense />
around the <EmployeeList />
. However, when I enter a value in the filter which triggers a change in the search params which then causes the data to refresh, I do not get the loading fallback which is defined in my suspense.Can still just leave the code as-is and loading.tsx will still work, use() is not required to trigger the suspense boundary
Morelet’s CrocodileOP
@Asian black bear's assumption was correct, my
EmployeeList
is a client component and I want the page to render the other components and just display the loading for the list component. This works perfectly for the initial page load, but when a change in the search params triggers a reload of the data in the EmployeeList
component it does not display the loading indicator. How do I get it to work after the initial page load?Morelet’s CrocodileOP
Ok, I figured it out. I need to provide a key on the
<Suspense key={query}/>
which triggers the loading on subseqent fetches.