Streaming
Ketika lo bikin halaman yang nge-load beberapa data sekaligus, lo bisa pake streaming supaya halaman tersebut bisa ditampilkan lebih cepat alias nggak nge-block proses rendering. Konsepnya sama kayak yang ada di Next.js, cuman beda caranya aja.
Anggap aja lo punya halaman detail produk yang nampilin inforasi produk dan review produk. Dari kedua data tersebut, yang paling penting adalah informasi produk, sedangkan review produk bisa ditampilin belakangan.
Contohnya kayak gini:
import type { Route } from "./+types/product";
import { Await } from "react-router";
import { Suspense } from "react";
export async function loader({ params }: Route.LoaderArgs) {
const product = await db.getProduct(params.pid);
// yang ini nggak usah lo `await`, biar bisa di-stream
const reviews = db.getProductReviews(params.pid);
return { product, reviews };
}
export default function Product({ loaderData }: Route.ComponentProps) {
return (
<div>
<h1>{loaderData.product.name}</h1>
<p>{loaderData.product.description}</p>
<Suspense fallback={<p>Loading reviews...</p>}>
<Await resolve={loaderData.reviews}>
{(reviews) => (
<ul>
{reviews.map((review) => (
<li key={review.id}>{review.content}</li>
))}
</ul>
)}
</Await>
</Suspense>
</div>
);
}Penjelasannya gini:
- Di
loader, kita ambil data produk dan review produk.- Data informasi produk ini penting, jadi kita
awaitsupaya bisa langsung ditampilin. - Sedangkan review produk kita nggak
await, supaya bisa di-stream.
- Data informasi produk ini penting, jadi kita
- Di dalam component
Product, kita pake<Await>dan<Suspense>buat nge-handle data review yang di-stream.<Await>bakal nunggu data review resolve dan nge-render list review lewat pattern render props.<Suspense>bakal nampilin fallback UI (dalam hal ini, "Loading reviews...") selama data review belum tersedia.
Basic-nya kayak gitu. Kalo seaindainya lo pake React 19, lo bisa pke React.use. Tapi, perlu diabstrak jadi dua komponen:
import type { Route } from "./+types/product";
import { Suspense } from "react-router";
import { ProductReviews } from "~/components/ProductReviews";
// kode loader yang sama
export default function Product({ loaderData }: Route.ComponentProps) {
return (
<div>
<h1>{loaderData.product.name}</h1>
<p>{loaderData.product.description}</p>
<Suspense fallback={<p>Loading reviews...</p>}>
<ProductReviews reviews={loaderData.reviews} />
</Suspense>
</div>
);
}Sementara isi dari komponen ProductReviews adalah:
import React from "react";
import { Review } from "~/libs/db/schema";
export function ProductReviews({ reviews }: { reviews: Promise<Review[]> }) {
const reviews = React.use(reviews);
return (
<ul>
{reviews.map((review) => (
<li key={review.id}>{review.content}</li>
))}
</ul>
);
}Bebas aja lo mau pake yang mana.
Diskusi
0 komentarBelum ada komentar.
Mulai diskusi