Next.js Lesson 7: Data Fetching
Next.js has powerful built-in data fetching with caching, revalidation, and parallel loading baked in.
Server Component Fetching
// Fetch in Server Component — simplest approach
async function ProductList() {
// Cached by default — won't re-fetch on every request
const products = await fetch("https://api.example.com/products", {
// Options:
cache: "no-store", // always fresh (SSR behavior)
next: { revalidate: 60 } // refresh every 60 seconds (ISR)
}).then(r => r.json());
return <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
}
Parallel Data Fetching
async function Dashboard() {
// Fetch in PARALLEL with Promise.all
const [users, posts, stats] = await Promise.all([
fetch("/api/users").then(r => r.json()),
fetch("/api/posts").then(r => r.json()),
fetch("/api/stats").then(r => r.json()),
]);
return (
<div>
<UserCount count={users.length} />
<PostList posts={posts} />
<StatsDashboard stats={stats} />
</div>
);
}
generateStaticParams (SSG)
// app/blog/[slug]/page.tsx
// Generate all blog post pages at BUILD TIME
export async function generateStaticParams() {
const posts = await fetch("https://api.example.com/posts").then(r => r.json());
return posts.map((post: { slug: string }) => ({
slug: post.slug,
}));
}
export default async function BlogPost({ params }: { params: { slug: string } }) {
const post = await fetch(`https://api.example.com/posts/${params.slug}`).then(r => r.json());
return <article><h1>{post.title}</h1><p>{post.body}</p></article>;
}
🏋️ Practice Task
Build a blog with static generation. Fetch all posts from jsonplaceholder in generateStaticParams. Generate /blog/[id] for each post. The page should show the post title, body, and author (fetch user separately using the post’s userId).
💡 Hint: Use Promise.all([fetch post, fetch user]) for parallel fetching in the page component.