Suspense is not working
Unanswered
Terek Sandpiper posted this in #help-forum
Terek SandpiperOP
I did everything according to the documentation, but a similar code running on me does not return a fallback. Has anyone encountered this in next 15.2.2?
<Suspense fallback={<div>Loading...</div>}>
<TestComp/>
</Suspense>
export default async function Posts() {
await new Promise((resolve) => setTimeout(resolve, 2000));
const data = await fetch('https://api.vercel.app/blog', { cache: 'no-store' })
const posts = await data.json()
return (
<ul>
{posts.map((post: any) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
12 Replies
Blood cockle
your suspense is wrapping <TestComp /> but your setTimeout is in "Posts" not "TestComp". what's in TestComp?
Terek SandpiperOP
I made a mistake, the Posts component is TestComp
Have you put a Loading.tsx next to the Posts route?
async function TitleCardsDataWrapper() {
const result = await getPartnersAndTitle()
return <div>{result?.data && <TitleCardsWrapper data={result.data} />}</div>
}
export default async function Page() {
return (
<PageRoot>
<PageRootHeader
Icon={<Users />}
title="Meu título"
description="Esta é a área administrativa da sua conta, onde você pode atualizar seus dados, alterar sua senha e incluir novos dependentes."
/>
<PageRootContent>
<LinkWrapper />
<Suspense fallback={<MyTitleCardSkeleton />}>
<TitleCardsDataWrapper />
</Suspense>
</PageRootContent>
</PageRoot>
)
}
const result = await getPartnersAndTitle()
return <div>{result?.data && <TitleCardsWrapper data={result.data} />}</div>
}
export default async function Page() {
return (
<PageRoot>
<PageRootHeader
Icon={<Users />}
title="Meu título"
description="Esta é a área administrativa da sua conta, onde você pode atualizar seus dados, alterar sua senha e incluir novos dependentes."
/>
<PageRootContent>
<LinkWrapper />
<Suspense fallback={<MyTitleCardSkeleton />}>
<TitleCardsDataWrapper />
</Suspense>
</PageRootContent>
</PageRoot>
)
}
Suspense just work if his children be a Promise<JSX.Element>
@danielvanc Have you put a Loading.tsx next to the Posts route?
Terek SandpiperOP
yes
@Yves async function TitleCardsDataWrapper() {
const result = await getPartnersAndTitle()
return <div>{result?.data && <TitleCardsWrapper data={result.data} />}</div>
}
export default async function Page() {
return (
<PageRoot>
<PageRootHeader
Icon={<Users />}
title="Meu título"
description="Esta é a área administrativa da sua conta, onde você pode atualizar seus dados, alterar sua senha e incluir novos dependentes."
/>
<PageRootContent>
<LinkWrapper />
<Suspense fallback={<MyTitleCardSkeleton />}>
<TitleCardsDataWrapper />
</Suspense>
</PageRootContent>
</PageRoot>
)
}
Terek SandpiperOP
That's what I've done. But the loading screen only appears when you go to this page, not when you first load
What’s your file structure? Maybe you’re missing a loading.tsx. Would be helpful to see that to have more context
Terek SandpiperOP
I use the app route
layout:
import MyHeader from '@components/ui/my/MyHeader';
import { getInfo } from '@/utils/data';
export default function Layout({ children }: { children: React.ReactNode }) {
const userPromise = getInfo();
return (
<div className="grid min-h-screen">
<MyHeader userPromise={userPromise} />
<section className='mt-16'>
{children}
</section>
</div>
);
}
MyHeader is a client component that accepts a Promise and processes it using use react
page:
import MyPayments from '../components/ui/my/MyPayments';
import { getInfo } from "@/utils/data";
export default async function Page() {
const userPromise = getInfo();
return (<MyPayments userPromise={userPromise}/>);
}