Server Component үндэс
Next.js App Router-н хамгийн гол шинэлэг зүйл бол React Server Component — серверт ажилладаг React component. Энэ ойлголтыг сайн эзэмшвэл Next.js-г үнэхээр хүчтэй хэрэглэж чадна.
Server Component гэж яг юу вэ?
Ердийн React component (Vite дахь) хөтөч дээр ажилладаг. Server Component харин сервер дээр ажилладаг бөгөөд хөтөч рүү зөвхөн HTML очдог — JavaScript очдоггүй.
// app/courses/page.tsx — Server Component (анхны төлөв)
// 'use client' байхгүй тул сервер дээр ажиллана
import { readFile } from "fs/promises";
import path from "path";
export default async function CoursesPage() {
// Файл системээс шууд уншиж болно — хөтчөөс боломжгүй!
const filePath = path.join(process.cwd(), "content/courses.json");
const data = await readFile(filePath, "utf-8");
const courses = JSON.parse(data);
return (
<main>
<h1>Сургалтууд</h1>
<ul>
{courses.map((course: { slug: string; title: string }) => (
<li key={course.slug}>{course.title}</li>
))}
</ul>
</main>
);
}
async/await шууд component дотор ашиглаж болно — Server Component-н хамгийн том давуу тал энэ!
Server Component-н давуу талууд
Bundle хэмжээ багасна — component-н код хөтөч рүү очдоггүй тул JavaScript bundle жижигсэнэ. Хэрэглэгч хуудсыг хурдан ачаална.
Аюулгүй байдал — database connection string, API key зэрэг нууц мэдээллийг server component дотор шууд ашиглаж болно. Хөтөч рүү алддаггүй.
Шууд өгөгдлийн сан — Supabase-с өгөгдөл татахад API route дамжуулах шаардлагагүй. Server component дотор шууд хийнэ:
// app/profile/page.tsx
import { createClient } from "@/lib/supabase/server";
import { redirect } from "next/navigation";
export default async function ProfilePage() {
const supabase = await createClient();
const {
data: { user },
} = await supabase.auth.getUser();
if (!user) {
redirect("/login"); // Нэвтрээгүй бол login руу шилжүүлнэ
}
const { data: profile } = await supabase
.from("profiles")
.select("username, xp, streak")
.eq("id", user.id)
.single();
return (
<main>
<h1>Сайн байна уу, {profile?.username}!</h1>
<p>XP: {profile?.xp}</p>
<p>Streak: {profile?.streak} өдөр</p>
</main>
);
}
Энэ бүх код сервер дээр ажиллана — хөтөч Supabase-н connection-г харахгүй.
Server Component ба Client Component харьцуулалт
| | Server Component | Client Component |
| ----------------------- | ---------------- | ---------------- |
| Ажилладаг газар | Сервер | Хөтөч |
| async/await | ✅ Болно | ❌ Болохгүй |
| Database шууд | ✅ Болно | ❌ Болохгүй |
| useState, useEffect | ❌ Болохгүй | ✅ Болно |
| Event handler | ❌ Болохгүй | ✅ Болно |
| Bundle-д орох | ❌ Ордоггүй | ✅ Ордог |
| Тэмдэглэгч | Байхгүй | 'use client' |
Хэзээ Client Component ашиглах вэ?
Зөвхөн дараах тохиолдолд 'use client' нэмнэ:
"use client";
import { useState } from "react";
// useState hook ашиглаж байгаа тул client component
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Тоо: {count}</p>
<button onClick={() => setCount(count + 1)}>Нэмэх</button>
</div>
);
}
'use client' нэмэх шалтгаанууд:
useState,useEffect,useRefзэрэг hook ашиглахonClick,onChangeзэрэг event handler ашиглахwindow,localStorageзэрэг browser API ашиглахusePathname,useRouterзэрэг navigation hook ашиглах
Зөв загвар — Server + Client хослуулах
Хамгийн зөв хандлага бол server component-г аль болох их, client component-г аль болох бага ашиглах. Ихэвчлэн server component дотор client component байрлуулна:
// app/courses/[courseSlug]/page.tsx — Server Component
import LessonSidebar from "@/components/lesson/LessonSidebar"; // Client
import { getCourse } from "@/lib/courses";
interface Props {
params: Promise<{ courseSlug: string }>;
}
export default async function CoursePage({ params }: Props) {
const { courseSlug } = await params;
const course = await getCourse(courseSlug); // Серверт өгөгдөл татна
return (
<div className="flex">
{/* Client component-д өгөгдлийг prop-оор дамжуулна */}
<LessonSidebar lessons={course.lessons} />
<main>
<h1>{course.title}</h1>
</main>
</div>
);
}
Server component-д татсан өгөгдлийг client component-д prop-оор дамжуулна — энэ бол зөв загвар.
Дараагийн хичээлд:
Client Component-г нарийвчлан судална. 'use client' хэзээ нэмэх, хэрэглэгчийн харилцан үйлчлэлийг хэрхэн зохицуулах тухай практик жишээгээр ойлгоно.