dev3 ·
I want the page shell to render immediately and a slow client-side list to load in without blocking. I heard you can pass a promise as a prop and read it with use(). How does that look?
#nextjs#react#use-hook#streaming
0
DEV3 Developer Forum
Every post is reviewed first. Usually reviewed within 24 hours.
I want the page shell to render immediately and a slow client-side list to load in without blocking. I heard you can pass a promise as a prop and read it with use(). How does that look?
#nextjs#react#use-hook#streaming
Start the fetch in a server component without awaiting it, pass the promise to a client component, and unwrap it with use() inside <Suspense>.
// app/orders/page.tsx (server)
import { Suspense } from "react";
import { getOrders } from "@/lib/orders";
import OrderList from "./order-list";
export default function Page() {
const ordersPromise = getOrders(); // not awaited
return (
<>
<h1>Orders</h1>
<Suspense fallback={<p>Loading orders...</p>}>
<OrderList ordersPromise={ordersPromise} />
</Suspense>
</>
);
}
// app/orders/order-list.tsx
"use client";
import { use, useState } from "react";
type Order = { id: string; total: number };
export default function OrderList({ ordersPromise }: { ordersPromise: Promise<Order[]> }) {
const orders = use(ordersPromise);
const [min, setMin] = useState(0);
return (
<>
<input type="number" onChange={(e) => setMin(+e.target.value)} />
<ul>{orders.filter((o) => o.total >= min).map((o) => <li key={o.id}>{o.id}</li>)}</ul>
</>
);
}
error.tsx) handles it. Catch inside getOrders if you want a fallback value.await inside it, wrapped in Suspense.