Server Components چیست

تا اینجا در این دوره، هر کامپوننتی که نوشتیم در مرورگر کاربر اجرا می‌شد. فصل بیست‌وچهارم یک پرسش اساسی را مطرح می‌کند: آیا لازم است همه کامپوننت‌ها در مرورگر اجرا شوند؟ پاسخ Server Components این است که بعضی کامپوننت‌ها می‌توانند فقط روی سرور (یا در زمان Build) اجرا شوند، و فقط نتیجه آن‌ها به مرورگر برسد، نه کدشان.

مشکلاتی که در فصل‌های قبل دیدیم

Server Components جواب چند مشکل آشنا است:

  • دریافت داده با تأخیر: در الگوی Fetch-on-render فصل چهاردهم، درخواست داده فقط پس از Render و Commit کامپوننت شروع می‌شد. کاربر ابتدا یک صفحه با Loading می‌دید و بعد از یک رفت‌وبرگشت شبکه، داده می‌رسید.
  • حجم جاوااسکریپت: Code Splitting فصل بیستم، بسته را به تکه‌های کوچک‌تر می‌شکند، اما کدی که کاربر لازم دارد همچنان باید دانلود و اجرا شود، حتی اگر کامپوننت هیچ تعاملی نداشته باشد.
  • افشای جزئیات: هر کدی که در مرورگر اجرا شود برای کاربر قابل مشاهده است. دسترسی مستقیم به پایگاه داده یا استفاده از یک کلید محرمانه در مرورگر ممکن نیست.

Server Component چیست

Server Component کامپوننتی است که در محیطی جدا از مرورگر اجرا می‌شود: روی سرور، یا یک‌بار در زمان Build. خروجی آن، توصیفی از رابط کاربری است که به مرورگر فرستاده می‌شود. تابع خود کامپوننت و کتابخانه‌هایی که فقط در آن استفاده شده‌اند، در بسته جاوااسکریپت مرورگر نمی‌آیند.

دو حالت اجرا

  • بدون سرور زنده: کامپوننت یک‌بار در زمان Build رندر می‌شود و خروجی آن مثل یک فایل ثابت عرضه می‌شود؛ مناسب محتوایی مثل یک پست وبلاگ که تغییرش کم است.
  • با سرور: کامپوننت با هر درخواست، روی سرور رندر می‌شود، و می‌تواند به داده‌های لحظه‌ای دسترسی داشته باشد.

کامپوننت async: await داخل Render

یکی از جذاب‌ترین ویژگی‌ها این است که Server Component می‌تواند یک تابع async باشد و مستقیماً داخل بدنه‌اش await کند:

jsx
// Server Component
async function ProductList() {
  const products = await db.products.findAll();

  return (
    <ul>
      {products.map((p) => (
        <li key={p.id}>{p.name}</li>
      ))}
    </ul>
  );
}

در این کد، هیچ useEffect، هیچ State برای loading و هیچ درخواست جداگانه از مرورگر وجود ندارد. داده روی سرور، پیش از ارسال خروجی، خوانده می‌شود. اگر بخواهید در مرورگر هم یک Promise را بخوانید، همان‌طور که در درس ۲۳-۸ دیدیم، Client Component نمی‌تواند async باشد و باید از use استفاده کند.

محدودیت: Server Component تعاملی نیست

چون Server Component پس از رسیدن به مرورگر دوباره اجرا نمی‌شود، نمی‌تواند هیچ چیز مرتبط با تعامل یا چرخه Render سمت کاربر را داشته باشد:

  • Hookهای State و Effect مثل useState و useEffect را نمی‌توان در آن استفاده کرد.
  • Event Handler مثل onClick در آن معنا ندارد.
  • APIهای مرورگر مثل window یا localStorage در دسترس نیستند.

بخش‌هایی که به این چیزها نیاز دارند، باید Client Component باشند؛ که در درس بعدی بررسی می‌شود.

یک سوءبرداشت رایج: Server Component با «use server» مشخص نمی‌شود

بسیاری تصور می‌کنند Server Componentها با دستور "use server" علامت‌گذاری می‌شوند. این درست نیست: برای Server Component هیچ Directive ای وجود ندارد. در فریم‌ورکی که از Server Components پشتیبانی می‌کند، کامپوننت‌ها به‌طور پیش‌فرض Server Component هستند. دستور "use client" برای علامت‌گذاری مرز Client Component است (درس ۲۴-۲ و ۲۴-۳). دستور "use server" برای Server Functionها (همان Actionهای سمت سرور فصل ۲۳) به کار می‌رود، نه خود کامپوننت.

تفاوت با SSR معمولی

این دو مفهوم اغلب با هم اشتباه گرفته می‌شوند، ولی یکی نیستند:

  • SSR: کامپوننت‌ها روی سرور به HTML تبدیل می‌شوند تا کاربر سریع‌تر صفحه را ببیند؛ اما همان کامپوننت‌ها بعداً در مرورگر هم دوباره اجرا (Hydrate) می‌شوند، پس کدشان هنوز به مرورگر می‌رسد.
  • Server Components: کد کامپوننت اصلاً به مرورگر نمی‌رود و در آن‌جا Hydrate نمی‌شود.

این دو در عمل با هم ترکیب می‌شوند، ولی هرکدام مشکل متفاوتی را حل می‌کنند.

وضعیت و نیازمندی‌ها

Server Components در React 19 پایدار هستند و بین نسخه‌های Minor شکسته نمی‌شوند. اما APIهای زیرین که یک Bundler یا Framework برای پیاده‌سازی آن‌ها استفاده می‌کند، از Semver پیروی نمی‌کنند و ممکن است بین نسخه‌های Minor شکسته شوند. به همین دلیل، استفاده عملی از Server Components معمولاً از طریق یک Framework با پشتیبانی داخلی انجام می‌شود، نه تنظیم دستی. نقش Frameworkها در درس ۲۴-۸ بررسی می‌شود.

چرا این درس مثال قابل اجرا ندارد

اجرای Server Component به یک محیط سروری و Bundler مناسب نیاز دارد که در ویرایشگر درون‌صفحه‌ای وجود ندارد. کدهای این درس را باید در یک پروژه با Framework مناسب اجرا کنید.

جمع‌بندی

Server Component کامپوننتی است که فقط روی سرور یا در زمان Build اجرا می‌شود و کدش به مرورگر نمی‌رسد. می‌تواند async باشد و مستقیماً داده بخواند، اما نمی‌تواند State، Effect، Event Handler یا APIهای مرورگر داشته باشد. Server Component نه با "use server" مشخص می‌شود و نه همان SSR است. این قابلیت در React 19 پایدار است و عملاً به یک Framework نیاز دارد. در درس بعدی، به Client Components می‌پردازیم.