Next.js এর হাতেখড়ি (পর্ব ৩) – Server Components vs Client Components

Next.js Server Components vs Client Components

পর্ব ১-এ hydration-এর কথা বলেছিলাম, একটা ধারণা যা প্লেইন React-এ নেই। এই পর্বে সেটার মূল কারণ বুঝব — Next.js-এ প্রতিটা কম্পোনেন্ট ডিফল্টভাবে Server Component, যা প্লেইন React-এর অভ্যাস থেকে সম্পূর্ণ আলাদা একটা মানসিকতা দাবি করে। এই পর্বটা এই সিরিজের সবচেয়ে গুরুত্বপূর্ণ কনসেপ্ট পর্ব — সময় নিয়ে ভালোভাবে বোঝা দরকার।

React এর হাতেখড়ি সিরিজে যা জানতাম

React এর হাতেখড়ি সিরিজে প্রতিটা কম্পোনেন্ট ব্রাউজারে চলত — useState, useEffect, ইভেন্ট হ্যান্ডলার — সব ব্রাউজারের JavaScript ইঞ্জিনে। Next.js-এ এটা বদলে যায়।

Server Component — ডিফল্ট আচরণ

Next.js App Router-এ প্রতিটা কম্পোনেন্ট ডিফল্টভাবে Server Component — মানে এটা সার্ভারে চলে, HTML তৈরি করে, আর সেই HTML-টাই ব্রাউজারে পাঠানো হয়। কম্পোনেন্টের JavaScript কোড ব্রাউজারে পাঠানোই হয় না।

// app/page.js — এটা একটা Server Component (কোনো বিশেষ কিছু লিখতে হয় না)
export default function HomePage() {
  return (
    <div>
      <h1>স্বাগতম</h1>
      <p>এই কম্পোনেন্ট সার্ভারে রেন্ডার হয়ে HTML হিসেবে পাঠানো হয়েছে।</p>
    </div>
  );
}

Server Component-এর সুবিধা

  • ব্রাউজারে কম JavaScript পাঠাতে হয় — দ্রুত লোড
  • সরাসরি ডেটাবেজ বা সিক্রেট API কল করা যায় (Firebase এর হাতেখড়ি পর্ব ১১-এর Cloud Functions-এর মতোই একটা নিরাপদ, সার্ভার-সাইড পরিবেশ)
  • SEO ভালো — সার্চ ইঞ্জিন পূর্ণ কনটেন্ট দেখতে পায়

Server Component যা করতে পারে না

  • useState, useEffect ব্যবহার করা যায় না
  • onClick, onChange-এর মতো ইভেন্ট হ্যান্ডলার কাজ করে না
  • window, localStorage-এর মতো ব্রাউজার API অ্যাক্সেস করা যায় না

Client Component — "use client"

ইন্টারঅ্যাক্টিভিটি লাগলে (বাটন ক্লিক, ফর্ম ইনপুট, State) — একটা ফাইলের একদম উপরে "use client" লিখে সেই কম্পোনেন্টকে Client Component বানাতে হয়।

// app/components/Counter.js
"use client"; // এই লাইনটাই সবকিছু বদলে দেয়

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>গোনা হয়েছে: {count}</p>
      <button onClick={() => setCount(count + 1)}>বাড়াও</button>
    </div>
  );
}

"use client" ছাড়া এই কোড চালানোর চেষ্টা করলে Next.js একটা এরর দেখাবে — useState only works in Client Components। এটাই সবচেয়ে সাধারণ প্রথম বাগ, যা নতুনরা এই ফ্রেমওয়ার্কে করে।

কখন কোনটা — সিদ্ধান্তের নিয়ম

দরকার টাইপ
স্ট্যাটিক কনটেন্ট, টেক্সট, লেআউট Server (ডিফল্ট, কিছু লিখতে হয় না)
সরাসরি ডেটাবেজ/API কল Server
useState, useEffect, onClick Client ("use client")
ফর্ম ইনপুট, মোডাল, ড্রপডাউন Client

নিয়ম সহজ করে বললে: ইউজারের সাথে সরাসরি ইন্টারঅ্যাকশন লাগলেই শুধু Client, বাকি সব ডিফল্ট Server রাখাই ভালো অভ্যাস।

দুটো একসাথে মেলানো

একটা Server Component-এর ভেতরে Client Component বসানো যায় — এটাই সবচেয়ে সাধারণ প্যাটার্ন, পুরো পেজকে Client না বানিয়ে শুধু ইন্টারঅ্যাক্টিভ অংশটুকু আলাদা করা।

// app/page.js — Server Component
import Counter from "./components/Counter"; // Client Component

export default function HomePage() {
  return (
    <div>
      <h1>স্বাগতম</h1> {/* সার্ভারে রেন্ডার হলো */}
      <p>এটা একটা স্ট্যাটিক প্যারাগ্রাফ।</p>

      <Counter /> {/* এই অংশটুকুই শুধু ব্রাউজারে ইন্টারঅ্যাক্টিভ */}
    </div>
  );
}

এখানে পুরো পেজের বেশিরভাগই সার্ভারে রেন্ডার হচ্ছে (দ্রুত, কম JS), শুধু Counter-এর জন্যই ব্রাউজারে JavaScript পাঠানো হচ্ছে — এটাই Next.js-এর দক্ষতার আসল রহস্য।

একটা গুরুত্বপূর্ণ নিয়ম — উল্টোটা করা যায় না

Server Component-এর ভেতর Client Component বসানো যায়, কিন্তু Client Component-এর ভেতর সরাসরি একটা নতুন Server Component ইমপোর্ট করে বসানো যায় না — কারণ Client Component ব্রাউজারে চলে, আর Server Component সার্ভারে চলার জন্যই বানানো।

// ❌ এটা কাজ করবে না
"use client";
import ServerOnlyComponent from "./ServerOnlyComponent"; // সমস্যা তৈরি করবে

// ✅ এর বদলে, Server Component থেকে children হিসেবে পাস করুন
// (এটা একটা অ্যাডভান্সড প্যাটার্ন, আপাতত মনে রাখুন — দরকার হলে Server Component থেকেই শুরু করুন)

ইন্টারেক্টিভ — Server নাকি Client?

নিচে বিভিন্ন কম্পোনেন্টের বর্ণনা দেওয়া আছে — ক্লিক করে দেখো সেটা Server নাকি Client Component হওয়া উচিত।

ভালো অভ্যাস

  • ডিফল্ট Server-এ থাকতে দিন — শুধু ইন্টারঅ্যাক্টিভিটি লাগলেই "use client" যোগ করুন
  • Client Component ছোট ও নির্দিষ্ট রাখুন — পুরো পেজ Client না বানিয়ে, শুধু বাটন বা ফর্মের অংশটুকু আলাদা কম্পোনেন্টে বের করুন (উপরের Counter উদাহরণের মতো)
  • এরর মেসেজ পড়ুন — "useState only works in Client Components"-এর মতো এরর দেখলে বুঝবেন উপরে "use client" ভুলে গেছেন

নিজে চেষ্টা করো

Exercise:

  1. একটা Server Component পেজ বানাও যাতে useState ব্যবহার করার চেষ্টা করো, এরর মেসেজটা লক্ষ করো।
  2. উপরের Counter Client Component নিজে বানাও, একটা Server Component পেজে সেটা বসাও।
  3. "View Page Source" দিয়ে দেখো — প্রাথমিক HTML-এ Counter-এর "0" দেখা যাচ্ছে কিনা (Server-এ প্রথমবার রেন্ডার হয়েছে), তারপর ক্লিক করে দেখো (ব্রাউজারে hydrate হয়ে ইন্টারঅ্যাক্টিভ হয়েছে)।
  4. একটা পেজে ৩টা কম্পোনেন্ট রাখো — দুটো Server, একটা Client — বুঝে নাও কীভাবে একসাথে কাজ করছে।

পরের পর্বে যা থাকছে

পরের পর্বে আমরা শিখব Data Fetching — Server Component-এর ভেতর থেকে সরাসরি fetch() কীভাবে ব্যবহার করতে হয়, Next.js-এর বিল্ট-ইন caching, আর কীভাবে ডেটা রিফ্রেশ (revalidate) করাতে হয়।

একটি মন্তব্য পোস্ট করুন

নবীনতর পূর্বতন

যোগাযোগ ফর্ম