Cara Kerja React Server Component di Next.js
React Server Components (RSC) adalah perubahan paling fundamental dalam ekosistem React sejak Hooks diperkenalkan. RSC memungkinkan komponen React dirender di SERVER, mengirimkan HTML siap pakai ke browser.
Perbandingan Rendering
+------------------------------------+------------------------------------+
| Client Component | Server Component |
| (useState, useEffect) | (default di App Router) |
+------------------------------------+------------------------------------+
| Dirender di browser | Dirender di server |
| JavaScript dikirim ke klien | Hanya HTML yang dikirim |
| Bisa akses localStorage, window | Tidak bisa akses browser API |
| Bisa pakai hooks (useState, dll) | Tidak bisa pakai hooks |
| Interaktif (event handlers) | Statis, perlu Client Component |
| Bundle size: BESAR | Bundle size: NOL |
+------------------------------------+------------------------------------+
Diagram Alur Data
USER REQUEST HALAMAN | v
+-----------------------+
| SERVER |
| +-----------------+ |
| | Server Comp #1 | | --- query DB langsung ---> +----------+
| | (RSC) | | <--- data dari DB --------- | Database |
| +--------+--------+ | +----------+
| | |
| +--------v--------+ |
| | Client Comp #2 | | --- perlu interaktivitas ---
| | ('use client') | | <--- JavaScript dikirim ----
| +-----------------+ |
| | |
| +--------v--------+ |
| | Server Comp #3 | | --- RSC lagi, statis ---
| | (RSC) | |
| +-----------------+ |
+-----------------------+
|
v
+-----------------------+
| BROWSER (Client) |
| HTML + minimal JS |
+-----------------------+
Server Component (default)
Di App Router, komponen adalah Server Component secara default:
// app/blog/page.tsx
// INI SERVER COMPONENT — tidak perlu 'use client'
import { prisma } from "@/lib/prisma";
export default async function BlogPage() {
// Langsung akses database! Tidak perlu API endpoint.
const posts = await prisma.blogPost.findMany({
where: { published: true },
orderBy: { createdAt: "desc" },
});
return (
<div>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
);
// Hasil: Hanya HTML yang dikirim ke browser
// Tidak ada JavaScript untuk komponen ini!
}
Client Component ('use client')
Hanya gunakan ketika Anda BUTUH interaktivitas:
// app/components/LikeButton.tsx
"use client"; // <-- directive ini yang membuatnya Client Component
import { useState } from "react";
export default function LikeButton({ postId }: { postId: string }) {
const [liked, setLiked] = useState(false);
return (
<button onClick={() => setLiked(!liked)}>
{liked ? "Unlike" : "Like"}
</button>
);
}
Panduan Memilih
| Kebutuhan | Pilih |
|---|---|
| Fetch data dari database | Server Component |
| Render konten statis | Server Component |
| SEO-friendly halaman | Server Component |
| Form input, tombol, interaktivitas | Client Component |
| useEffect, useState | Client Component |
| Animasi kompleks | Client Component |
| API key rahasia | Server Component |
Komposisi: Server + Client
Server Component bisa me-render Client Component, tapi tidak sebaliknya:
// ✅ BENAR: Server component merender client component
// app/page.tsx (Server Component)
import LikeButton from "./LikeButton"; // Client Component
export default function Page() {
const posts = await getPosts(); // server-side
return <LikeButton postId={posts[0].id} />;
}
// ❌ SALAH: Client component tidak bisa import server component
// app/components/ClientComp.tsx
"use client";
import ServerComp from "./ServerComp"; // ERROR!
Manfaat RSC untuk Portfolio
- SEO最大化: Semua konten terindex oleh Google
- Performa: Bundle size minimal = loading cepat
- Keamanan: Database credentials tidak bocor ke klien
- Developer Experience: Query langsung di komponen
Kesimpulan: RSC bukan sekadar fitur baru — ia adalah perubahan paradigma dalam cara kita membangun web. Server-first, client-when-needed.