تفاوت React و Next.js
در درس قبل دیدیم که Next.js یک فریمورک فولاستک مبتنی بر React است. اکنون باید دقیق مشخص کنیم که چه بخشهایی را React ارائه میدهد و چه بخشهایی را Next.js اضافه میکند. درک این مرز به شما کمک میکند هنگام مشکلیابی بدانید باید سراغ مستندات کدامیک بروید و هنگام طراحی برنامه بدانید هر کار را کجا انجام دهید.
پیشنیاز
- درس
CH01-S01: Next.js چیست و چه مسئلهای را حل میکند؟ - آشنایی پایه با کامپوننتها، JSX، Props و State در React
توضیح شهودی: کتابخانه در برابر فریمورک
React یک کتابخانه برای ساخت رابط کاربری است. کار اصلی آن این است که بگوید «با این دادهها، رابط کاربری چه شکلی دارد» و هنگام تغییر داده، رابط را بهروز کند. React عمداً دربارهی مسیریابی، دریافت داده، ساختار پروژه، ابزار Build و استقرار تصمیم نمیگیرد و این انتخابها را به شما میسپارد.
Next.js یک فریمورک است. یعنی علاوه بر استفاده از React برای رابط کاربری، دربارهی ساختار پروژه، مسیریابی، نحوهی رندر، دریافت داده، کش و Build تصمیم گرفته و ابزار آماده ارائه میکند. تفاوت اصلی در همین است: React ابزار میدهد، Next.js یک مسیر ساختهشده و یکپارچه میدهد.
نکتهی مهم این است که این دو رقیب نیستند. وقتی در Next.js کامپوننت مینویسید، کامپوننت React نوشتهاید و همهی دانشی که از React دارید (JSX، Props، State، Hookها) همچنان کاربرد دارد.
توضیح فنی: هر کدام مسئول چه بخشی است؟
| موضوع | React | Next.js |
|---|---|---|
| نوع ابزار | کتابخانهی رابط کاربری | فریمورک فولاستک مبتنی بر React |
| کامپوننتها، JSX، State و Hookها | تعریف و ارائه میکند | از همانها استفاده میکند و مفهوم Server Component را هم در کنار آن به کار میگیرد |
| مسیریابی | ندارد؛ باید کتابخانهی جداگانه انتخاب کنید | داخلی و مبتنی بر ساختار پوشهها و فایلها |
| ساختار پروژه | تعیین نمیکند | قراردادهای مشخص (مثل page.tsx و layout.tsx) |
| رندر روی سرور | قابلیتهای پایه فراهم است، اما راهاندازی کامل با شماست | بهصورت یکپارچه و آماده در چارچوب برنامه |
| دریافت داده | راهحل یکپارچهی از پیش تعیینشده ندارد | دریافت داده در Server Componentها و ابزارهای کش و بازاعتبارسنجی |
| منطق سمت سرور | پروژهی سرور جدا لازم است | Server Actions و Route Handlers در همان پروژه |
| Build و ابزار توسعه | باید انتخاب و پیکربندی شود | پیشفرض آماده (از جمله Turbopack در Next.js 16) |
| بهینهسازی تصویر، فونت و Metadata | ندارد؛ به کتابخانهها و پیکربندی خودتان وابسته است | ابزارهای داخلی مانند next/image و next/font |
یک نکتهی مهم: رابطهی دو ابزار در عمل
React خودش هم راههای ساخت برنامه را پیشنهاد میکند و مستندات رسمی آن، استفاده از یک فریمورک را برای پروژههای جدید توصیه میکند؛ Next.js یکی از این فریمورکهاست. همچنین قابلیتهایی مثل Server Components بخشی از ایدهی React هستند و Next.js آنها را در یک برنامهی کامل به کار میگیرد. بنابراین مرز این دو همیشه بهسادگی «این از React است و آن از Next.js» نیست، اما یک قاعدهی عملی وجود دارد:
- اگر موضوع به کامپوننت، State، Props، Hook یا JSX مربوط است، سراغ مستندات React بروید.
- اگر موضوع به مسیر، Layout، دریافت داده در سطح برنامه، کش، Route Handler، Metadata یا استقرار مربوط است، سراغ مستندات Next.js بروید.
مثال واقعی: همان صفحه در دو رویکرد
فرض کنید در DevNotes میخواهیم صفحهای داشته باشیم که فهرست نوشتهها را نشان بدهد. ببینید هر رویکرد چه کارهایی از شما میخواهد.
رویکرد React خالص (اجرا در مرورگر)
- یک ابزار Build انتخاب و پیکربندی کنید.
- یک کتابخانهی مسیریابی نصب کنید و مسیر
/postsرا در پیکربندی آن تعریف کنید. - کامپوننت صفحه را بنویسید و دادهها را پس از بارگذاری، با درخواست از مرورگر دریافت کنید.
- حالتهای انتظار و خطا را با State دستی مدیریت کنید.
- برای ذخیرهی نوشتهها یک سرور جداگانه بسازید.
رویکرد Next.js
- پروژه با یک فرمان ساخته میشود و ابزار Build آماده است.
- فایل
app/posts/page.tsxرا میسازید؛ مسیر/postsخودکار ایجاد میشود. - داده را داخل همین کامپوننت روی سرور میخوانید.
- برای انتظار و خطا فایلهای قراردادی مثل
loading.tsxوerror.tsxوجود دارند. - منطق ذخیرهسازی را میتوانید در همان پروژه بنویسید.
مقایسهی کد: همان صفحه، دو شکل نوشتن
دو نمونهی زیر کاملاً سادهشدهاند و فقط برای نشاندادن تفاوت الگوی کار هستند. نمونهی اول فرض میکند در یک پروژهی React خالص، فهرست نوشتهها از یک آدرس API در مرورگر دریافت میشود:
React خالص: دریافت داده در مرورگر
import { useEffect, useState } from "react";
type Post = { id: number; title: string };
export default function PostsPage() {
const [posts, setPosts] = useState<Post[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch("/api/posts")
.then((res) => res.json())
.then((data) => setPosts(data))
.finally(() => setLoading(false));
}, []);
if (loading) return <p>در حال بارگذاری...</p>;
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}Next.js: خواندن داده در Server Component
// app/posts/page.tsx
type Post = { id: number; title: string };
async function getPosts(): Promise<Post[]> {
// در این مثال آموزشی، دادهی نمونه برمیگردد.
return [
{ id: 1, title: "آشنایی با Next.js" },
{ id: 2, title: "مسیریابی در App Router" },
];
}
export default async function PostsPage() {
const posts = await getPosts();
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}توضیح کد
-
در نمونهی React خالص، چون کد در مرورگر اجرا میشود، ابتدا یک رندر بدون داده انجام میشود، سپس
useEffectدرخواست میفرستد و بعد از دریافت پاسخ، State تغییر میکند. مدیریتloadingهم با خودتان است. -
در نمونهی Next.js، کامپوننت
asyncاست و مستقیماًawaitمیکند. این کار در Server Component مجاز است. نتیجهی رندر از سمت سرور آماده میشود و فهرست نوشتهها همراه HTML اولیه به مرورگر میرسد. -
در نمونهی Next.js نه
useStateلازم شد و نهuseEffect؛ چون این کامپوننت روی سرور اجرا میشود و State یا Effect مرورگر در آن معنا ندارد. -
تابع
getPostsدر این مثال فقط دادهی نمونه برمیگرداند. در فصل ۵ لایهی دسترسی به داده را درست میسازیم و در فصل ۱۲ آن را به Prisma وصل میکنیم.
رفتار مورد انتظار
هر دو نمونه در نهایت یک فهرست از عنوان نوشتهها نشان میدهند. تفاوت در این است که در نمونهی React خالص کاربر ابتدا پیام «در حال بارگذاری...» را میبیند و بعد فهرست ظاهر میشود، ولی در نمونهی Next.js فهرست از ابتدا در HTML اولیهی صفحه وجود دارد.
آیا Next.js همیشه بهتر است؟
نه لزوماً. Next.js برای برنامههایی که صفحات متعدد، محتوای عمومی، نیاز به SEO، دریافت داده از سرور و منطق سمت سرور دارند انتخاب بسیار مناسبی است. اما برای یک ابزار کوچک و کاملاً سمت مرورگر، یک ویجت قابلجاسازی یا موارد مشابه که این نیازها را ندارند، ممکن است یک راهحل سبکتر کافی باشد. انتخاب باید بر اساس نیاز پروژه باشد.
جمعبندی
- React کتابخانهای برای ساخت رابط کاربری با کامپوننتهاست؛ Next.js فریمورکی است که روی React ساخته شده و ساختار برنامه را هم تعیین میکند.
- Next.js جایگزین React نیست؛ دانش React در Next.js مستقیماً کاربرد دارد.
- مسیریابی، Layout، دریافت داده در سطح برنامه، کش، Route Handler، Server Action و استقرار از ابزارهایی هستند که Next.js ارائه میکند.
- در Next.js کامپوننتها بهصورت پیشفرض Server Component هستند و میتوانند داده را مستقیم و روی سرور بخوانند.
- در درس بعد (
CH01-S03) پیشنیازها و محیط توسعه را آماده میکنیم.
