Next.js cho phép lấy dữ liệu ngay trong Server Component bằng async/await. Bài này trình bày cách gọi API và CSDL, lấy song song, kiểm soát cache và làm mới dữ liệu, hiển thị dần bằng Suspense (streaming) và tạo trang tĩnh cho route động.
Bạn sẽ học được
- Lấy dữ liệu trong Server Component
- Lấy song song với Promise.all
- Kiểm soát cache, revalidate
- Streaming với Suspense và loading.tsx
Một số khái niệm
- Trang động: render mỗi lần có yêu cầu (dữ liệu luôn mới).
- Trang tĩnh: render lúc build, phục vụ rất nhanh.
- Revalidate: làm mới trang tĩnh sau một khoảng thời gian hoặc khi dữ liệu thay đổi.
- Streaming: gửi phần sẵn sàng trước, phần chậm hiện sau với khung chờ.
Lấy dữ liệu
// Gọi song song cho nhanh
export default async function TongQuan() {
const [lop, sv] = await Promise.all([
fetch(API + '/lop').then(r => r.json()),
fetch(API + '/sinhvien', { cache: 'no-store' }).then(r => r.json()), // luôn mới
]);
return <p>{lop.length} lớp, {sv.tong} sinh viên</p>;
}// Làm mới định kỳ (giây)
fetch(API + '/tin-tuc', { next: { revalidate: 300 } });
// Gắn thẻ để làm mới theo yêu cầu
fetch(API + '/sinhvien', { next: { tags: ['sinhvien'] } });
// ... sau khi thêm sinh viên (trong Server Action):
import { revalidateTag, revalidatePath } from 'next/cache';
revalidateTag('sinhvien'); revalidatePath('/sinhvien');Streaming với Suspense
import { Suspense } from 'react';
export default function Trang() {
return (
<>
<h1 className="text-2xl font-bold">Bảng điều khiển</h1>
<Suspense fallback={<div className="h-24 animate-pulse rounded bg-slate-200" />}>
<ThongKeCham /> {/* async component tải chậm */}
</Suspense>
</>
);
}Trang tĩnh cho route động
// app/bai-viet/[slug]/page.tsx
export async function generateStaticParams() {
const ds = await fetch(API + '/bai-viet').then(r => r.json());
return ds.map((b: { slug: string }) => ({ slug: b.slug })); // build sẵn từng trang
}Mẹo hay
Đặt hàm lấy dữ liệu trong tệp riêng (vd. src/lib/api.ts) với import "server-only" để dùng lại và giữ khóa API an toàn.
Lưu ý
Cơ chế cache của Next.js thay đổi giữa các phiên bản; luôn kiểm tra bằng npm run build: Terminal liệt kê trang nào tĩnh (○) và động (ƒ).
Thực hành
- Hiển thị danh sách lớp và sinh viên, lấy song song.
- Thêm loading.tsx dạng skeleton.
- Bọc phần thống kê chậm bằng Suspense.
- Tạo trang tĩnh /bai-viet/[slug] với generateStaticParams.
Tóm tắt bài học
- async/await trực tiếp trong Server Component.
- cache: no-store, revalidate, tags.
- Suspense và loading.tsx cho streaming.
- generateStaticParams tạo trang tĩnh.