WisarWisar
Dasturlash kitobi/13-QISM — NextJS46 daqiqa

13.3-bob: Server Components vs Client Components

13-QISM — Next.js · 3-mavzu


1. Kirish va motivatsiya

Bu — Next.js App Router'ning eng muhim, eng inqilobiy va eng ko'p chalkashtiriladigan tushunchasi. 13.1 va 13.2-boblarda biz "use client" va async komponentlarni ko'rdik, lekin endi ularning ortidagi g'oyani — kod qaerda ishlaydi (server'da yoki brauzer'da) degan tub savolni — chuqur o'rganamiz. Bu savol React'ning 20 yillik tarixida yangi: ilgari butun React kodi brauzer'da ishlardi (SPA — 11.3), endi esa Next.js (React Server Components — RSC) bilan ba'zi komponentlar server'da, ba'zilari brauzer'da ishlaydi. Bu farqni tushunmasdan, Next.js'da to'g'ri, tez, samarali ilova yozib bo'lmaydi (eng keng xatolar manbai aynan shu yerda).

Markaziy g'oya shunday: Server Components (default — har komponent server'da ishlaydi, agar boshqacha aytmasangiz) tez (server'da render — brauzerga tayyor HTML), xavfsiz (server'da — API kalit, DB to'g'ridan — brauzerga chiqmaydi), ma'lumotga yaqin (server'da to'g'ridan DB/API — await), va yengil (komponent JavaScript'i brauzerga yuborilmaydi — kam bundle). Client Components ("use client") esa interaktivlik (state, hodisa, hook, brauzer API) beradi — lekin ular brauzer'da ishlaydi (JavaScript yuboriladi). To'g'ri strategiya — ko'p qism Server Component (statik, ma'lumot) + oz interaktiv qism Client Component (tugma, forma). Bu — Next.js'ning "server-first" falsafasi va eng katta performance afzalligi.

Bu bob: muammo (kod qaerda ishlaydi), Server Components (default — nima, foydalar), Client Components ("use client" — interaktivlik), qaysi qachon (qaror), kompozitsiya (server client'ni import qila oladi, teskari emas), "use client" chegarasi (import'larga tarqaladi), ma'lumot uzatish (server client — props, serializable), children naqshi (server'ni client ichida uzatish), server-only kod himoyasi (secrets/DB), keng xatolar (server'da hook, client'da server import, non-serializable props), hydration, 3-tomon komponentlar, context/provider (Client chegarasi), "use server" (Server Actions ko'prigi), va RSC payload / App Router chegarasi. Har mavzu to'liq, har kod misolida maqsad + izoh + "nima qiladi" bilan ochib beriladi.

O'xshatish: Server va Client Components — bu restoran oshxonasi va zal. Server Component — bu oshxona (server): taom shu yerda tayyorlanadi (render), mahsulotlarga to'g'ridan kirish bor (DB, API, secret — oshxonada, mehmon ko'rmaydi), va tayyor taom (HTML) zalga chiqadi. Mehmon (brauzer) oshxona jihozlarini (komponent JavaScript) ko'rmaydi ham — faqat tayyor taomni (kam yuk). Client Component — bu zal (brauzer): bu yerda mehmon bilan jonli muloqot bo'ladi (interaktivlik — tugma bosish, forma to'ldirish, jonli o'zgarishlar) — chunki mehmon shu yerda. Lekin zalga oshxona secretlari (DB parol) chiqmaydi (xavfsizlik). To'g'ri restoran — katta oshxona (ko'p ish server'da — tez, xavfsiz, kam yuk) + faqat kerakli zal xizmatlari (interaktiv qismlar). Hammasini zalda qilish (SPA) — sekin va xavfsiz emas; hammasini oshxonada (interaktivliksiz) — jonsiz. Balans — server-first.

Nega muhim?

  • Next.js'ning yuragi — Server/Client farqini tushynmasdan Next.js'da ishlab bo'lmaydi (eng keng xato).
  • Performance — Server Components kam JavaScript brauzerga (tez yuklanish — Next.js'ning asosiy afzalligi).
  • Xavfsizlik — server'da secret/DB to'g'ridan (brauzerga chiqmaydi — 10.11).
  • Soddaroq ma'lumot — server'da await fetch (useEffect/useState/loading yo'q — 11.5'dagi og'riq).

2. Nazariya — chuqur tushuntirish

2.1. Muammo — kod qaerda ishlaydi

text
  TUB SAVOL: React komponent kodi QAERDA ishlaydi?

  ESKI (SPA — 11.3): HAMMA komponent BRAUZER'da:
  Brauzep ──► barcha JS yuklanadi ──► React ishlaydi ──► UI quriladi
   barcha kod (komponent, mantiq) brauzerga yuboriladi va ishlaydi
   muammo: katta JS (sekin), secret brauzerda (xavfli), ma'lumot brauzerda olinadi

  YANGI (Next.js RSC): KOMPONENT IKKI JOYDA ishlaydi:
  ┌────────────────────────────────────────────────────────────┐
  │ SERVER COMPONENT — server'da render (tayyor HTML brauzerga) │
  │    tez, xavfsiz, ma'lumot yaqin, JS brauzerga yo'q          │
  │ CLIENT COMPONENT — brauzer'da (interaktivlik)               │
  │    state, hodisa, hook — JS brauzerga yuboriladi           │
  └────────────────────────────────────────────────────────────┘

   Yangi savol: BU komponent server'da yoki client'da ishlashi kerakmi?
   Default — SERVER (Next.js App Router); interaktivlik kerak bo'lsa — client

Muammo — kod qaerda ishlaydi — Server/Client Components'ning tub savoli. Eski SPA modelida (11.3) barcha React komponent brauzer'da ishlardi: server bo'sh HTML berar, brauzer butun JavaScript'ni yuklar, React ishlar, UI qo'shilardi. Bu uch muammoni keltirardi: (1) katta JavaScript brauzerga yuboriladi (sekin yuklanish); (2) secret (API kalit) brauzerda bo'lsa xavfli 10.11-bob; (3) ma'lumot brauzerda olinar (useEffect+fetch — 11.5 — og'riq). Yangi Next.js modelida (React Server Components — RSC) komponent ikki joyda ishlaydi: Server Component (server'da render — tayyor HTML brauzerga; tez, xavfsiz, ma'lumotga yaqin, komponent JavaScript brauzerga yuborilmaydi) yoki Client Component (brauzer'da — interaktivlik: state, hodisa, hook; JavaScript brauzerga yuboriladi). Ikki nuqta: (1) endi har komponent uchun yangi savol — bu komponent server'da yoki client'da ishlashi kerakmi?; (2) Next.js App Router'da default — server (har komponent server'da, agar "use client" demasangiz), interaktivlik kerak bo'lganda client. Bu savol — Next.js'da har komponent yozishda beriladi, va to'g'ri javob ilova tezligi va xavfsizligini belgilaydi.

2.2. Server Components — default, foydalari

text
  SERVER COMPONENT — server'da render (App Router'da DEFAULT — hech narsa yozmasang):

  // app/products/page.tsx — Server Component (default — "use client" YO'Q)
  export default async function ProductsPage() {
    const products = await db.product.findMany();   //  DB'dan TO'G'RIDAN (server'da)
    return <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
  }

  FOYDALARI (4 katta):
  1. TEZLIK — server tayyor HTML beradi (brauzer darrov ko'radi — SEO, kam kutish)
  2. XAVFSIZLIK — server'da API kalit, DB to'g'ridan (brauzerga CHIQMAYDI — 10.11)
  3. MA'LUMOTGA YAQIN — server'da await fetch/DB (useEffect/loading YO'Q — 13.5)
  4. KAM JAVASCRIPT — komponent JS brauzerga YUBORILMAYDI (yengil bundle — tez)

  SERVER COMPONENT QILA OLMAYDI:
   useState, useEffect, hook (server'da yo'q)
   onClick, onChange (interaktivlik — brauzer kerak)
   brauzer API (window, localStorage)

   Server Component — DEFAULT (tez/xavfsiz/ma'lumot/yengil); lekin INTERAKTIV emas
   Statik kontent, ma'lumot ko'rsatish  Server Component (ko'p ilova shu)

Server Components — default, foydalari — App Router'ning asosiy komponent turi. Server Component — server'da render bo'ladigan komponent, va App Router'da bu default (hech narsa yozmasangiz — "use client" yo'q — komponent Server Component). Misol: export default async function ProductsPage() { const products = await db.product.findMany(); ... } — komponent server'da ishlaydi, shuning uchun ma'lumotlar bazasidan to'g'ridan (ORM — Prisma — 6.12) ma'lumot ola oladi (brauzer'da DB'ga to'g'ridan ulanish mumkin emas edi). 4 katta foyda: (1) tezlik — server tayyor HTML beradi (brauzer darrov ko'radi — SEO, kam kutish — 13.1: 2.1); (2) xavfsizlik — server'da API kalit, DB parol, to'g'ridan DB — bular brauzerga chiqmaydi 10.11-bob; (3) ma'lumotga yaqin — server'da await fetch/DB (useEffect/useState/loading yo'q — 13.5 — 11.5'dagi og'riq yo'qoladi); (4) kam JavaScript — komponent JavaScript'i brauzerga yuborilmaydi (faqat HTML — yengil bundle, tez). Server Component qila olmaydi: useState/useEffect/hook (server'da yo'q), onClick/onChange (interaktivlik — brauzer kerak), brauzer API (window, localStorage). Ikki nuqta: (1) Server Component — default (tez/xavfsiz/ma'lumot/yengil), lekin interaktiv emas; (2) statik kontent va ma'lumot ko'rsatish Server Component (ko'p ilova katta qismi shu — sarlavha, ro'yxat, kontent). Bu — Next.js'ning "server-first" falsafasining asosi.

2.3. Client Components — "use client", interaktivlik

text
  CLIENT COMPONENT — brauzer'da ishlaydi ("use client" direktivasi):

  "use client";   //  faylning ENG TEPACIDA (komponentni client qiladi)

  import { useState } from "react";

  export default function Counter() {
    const [count, setCount] = useState(0);   // hook — faqat client'da
    return <button onClick={() => setCount(count + 1)}>{count}</button>;  // onClick — interaktiv
  }

  CLIENT COMPONENT QILA OLADI (Server qila olmaydigan):
   useState, useEffect, useContext, custom hook 11.5-bob
   onClick, onChange, onSubmit (hodisalar — interaktivlik)
   brauzer API (window, localStorage, navigator)
   Class komponent, 3-tomon interaktiv kutubxona (Framer Motion — 11.16)

  NARXI (client'ning "qiymati"):
  - JavaScript brauzerga yuboriladi (Server'dan ko'proq yuk)
  - server'dan render bo'ladi (hydration — 2.11), keyin brauzer'da "jonlanadi"

   "use client" — komponentni interaktiv qiladi (state/hodisa/hook); lekin JS brauzerga
   Faqat INTERAKTIVLIK kerak bo'lganda (tugma, forma, modal) — aks holda Server (yengilroq)

Client Components — "use client", interaktivlik — interaktivlik kerak bo'lganda. Client Component — brauzer'da ishlaydigan komponent; uni belgilash uchun faylning eng tepasiga "use client" direktivasini yozasiz. Misol: "use client"; ... export default function Counter() { const [count, setCount] = useState(0); return <button onClick={...}>{count}</button> } — endi useState va onClick ishlaydi (brauzer'da). Client Component qila oladi (Server qila olmaydigan narsani — 2.2): useState/useEffect/useContext/custom hook 11.5-bob, onClick/onChange/onSubmit (hodisalar — interaktivlik), brauzer API (window, localStorage, navigator), class komponent, va 3-tomon interaktiv kutubxonalar (Framer Motion — 11.16, chart, map). Narxi: Client Component'ning JavaScript'i brauzerga yuboriladi (Server'dan ko'proq yuk), va u avval server'da render bo'ladi (HTML), keyin brauzer'da "jonlanadi" (hydration — 2.11 — JavaScript ulanadi). Ikki nuqta: (1) "use client" — komponentni interaktiv qiladi (state/hodisa/hook), lekin JavaScript brauzerga yuboriladi; (2) faqat interaktivlik kerak bo'lganda ishlatiladi (tugma, forma, modal, animatsiya) — aks holda komponent Server Component bo'lib qoladi (yengilroq, tezroq). Demak "use client" — "bu komponent (va u import qilgan narsalar) brauzer'da ishlasin" degan signal.

2.4. Qaysi qachon — qaror

text
  SERVER yoki CLIENT — TANLASH (har komponent uchun):

  ┌──────────────────────────────┬─────────────────────────────┐
  │ SERVER COMPONENT (default)   │ CLIENT COMPONENT ("use client")│
  ├──────────────────────────────┼─────────────────────────────┤
  │  Ma'lumot olish (DB/API)     │  useState/useEffect/hook     │
  │  Statik kontent ko'rsatish   │  onClick/onChange (hodisa)   │
  │  Secret/API kalit ishlatish  │  brauzer API (window/storage)│
  │  Katta kutubxona (markdown) │  interaktivlik (modal/forma) │
  │  SEO muhim kontent          │  3-tomon interaktiv (chart)  │
  └──────────────────────────────┴─────────────────────────────┘

  STRATEGIYA: "use client"ni PASTGA suyab (chegarani barglarga yaqin):
   ko'p qism Server (statik, ma'lumot); faqat INTERAKTIV barglar Client
   masalan: butun sahifa Server, faqat "Yoqdi" tugmasi Client

   Default Server; "use client" faqat zarurat (interaktivlik) — chegarani pastga surish
   "Bu komponentga interaktivlik kerakmi?" — YO'Q  Server; HA  Client

Qaysi qachon — qaror — har komponent uchun Server yoki Client tanlash. Server Component (default): ma'lumot olish (DB/API), statik kontent ko'rsatish, secret/API kalit ishlatish, katta kutubxona (masalan markdown render — server'da, brauzerga yuborilmasin), SEO muhim kontent. Client Component ("use client"): useState/useEffect/hook, onClick/onChange (hodisa), brauzer API (window/localStorage), interaktivlik (modal/forma/dropdown), 3-tomon interaktiv (chart, map, animatsiya). Eng muhim strategiya"use client"ni pastga suyab (chegarani "barglarga" — eng pastdagi interaktiv komponentlarga — yaqin tutish): ko'p qism Server Component (statik, ma'lumot — tez, yengil), faqat interaktiv barglar Client Component. Masalan: butun mahsulot sahifasi Server (sarlavha, narx, tavsif — ma'lumot, SEO), faqat "Savatga qo'sh" tugmasi Client (interaktiv). Ikki nuqta: (1) default Server, "use client" faqat zarurat (interaktivlik) — chegarani pastga suriladi (yuqori komponentga "use client" qo'yilsa, butun ostki daraxt client bo'ladi — 2.6 — keraksiz JavaScript); (2) oddiy test savoli — "bu komponentga interaktivlik (state/hodisa) kerakmi?" — yo'q Server (yengilroq); ha Client. Bu qaror — har Next.js komponentida beriladi va ilova performance/xavfsizligini belgilaydi.

2.5. Kompozitsiya — server client'ni import qiladi

text
  ASOSIY QOIDA: Server Component CLIENT'ni import qila oladi (teskari MURAKKAB):

   SERVER ichida CLIENT (oddiy — eng keng naqsh):
  // app/page.tsx (Server)
  import Counter from "./Counter";   // Counter — Client ("use client")
  export default async function Page() {
    const data = await fetch(...);    // server ma'lumot
    return (
      <div>
        <h1>{data.title}</h1>          {/* server — statik */}
        <Counter />                    {/* client — interaktiv (server ichida) */}
      </div>
    );
  }

   CLIENT ichida SERVER'ni to'g'ridan import — ISHLAMAYDI:
  // Client Component server komponentni import qila olmaydi (server'da render bo'lgan)
  //  o'rniga: server'ni CHILDREN/PROPS orqali uzat 2.7-bob

  ┌────────────────────────────────────────────────────────────┐
  │ Server  Client import: OK (server ichida interaktiv qism)  │
  │ Client  Server import: YO'Q (children/props orqali — 2.7)  │
  └────────────────────────────────────────────────────────────┘

   Server Component Client'ni import qila oladi (eng keng — server ichida interaktiv barg)
   Client Server'ni to'g'ridan import qila olmaydi (children orqali uzatiladi — 2.7)

Kompozitsiya — server client'ni import qiladi — Server/Client'ning birga ishlash qoidasi. Asosiy qoida: Server Component Client Component'ni import qila oladi (oddiy, eng keng naqsh), lekin Client Component Server'ni to'g'ridan import qila olmaydi (murakkabroq — 2.7). Server ichida Client ( — eng keng): // app/page.tsx (Server) ichida import Counter from "./Counter" (Counter — Client) va <Counter />ni render qilish — server'da ma'lumot olib (statik kontent), faqat interaktiv qismni (Counter) Client qilish (13.1: Misol 10). Bu naqsh ishlaydi, chunki Next.js server'da render qilishda Client Component uchun "joy zaxiralaydi" (placeholder), keyin brauzer'da uni "jonlantiradi" (hydration). Client ichida Server ( — to'g'ridan import ishlamaydi): Client Component server komponentni to'g'ridan import qila olmaydi (chunki Client brauzer'da ishlaydi, Server esa server'da render bo'lgan — ular har xil muhitda); o'rniga server komponentni children yoki props orqali uzatasiz 2.7-bob. Ikki nuqta: (1) Server Client import OK (server ichida interaktiv barg — eng keng naqsh); (2) Client Server import yo'q (children/props orqali — 2.7). Bu qoidani tushunish — Server/Client'ni to'g'ri birlashtirishning kaliti (eng keng tuzoq — Client ichida server import qilishga urinish).

2.6. "use client" chegarasi (import'larga tarqaladi)

text
  MUHIM: "use client" — komponentga + uning BARCHA IMPORT'lariga tarqaladi (cascade):

  // app/Dashboard.tsx
  "use client";                        //  bu fayl client
  import Chart from "./Chart";         // Chart ham CLIENT bo'ladi (import qilindi)
  import { formatDate } from "./utils"; // utils ham client'da ishlaydi

   "use client" qo'ygan komponent + u import qilgan HAMMA narsa — CLIENT

  TUZOQ: "use client"ni JUDA YUQORIGA qo'yish:
   app/layout.tsx'ga "use client"  BUTUN ilova client (Server foydasi yo'qoladi!)
   "use client"ni faqat KERAKLI (interaktiv) komponentga (pastga — 2.4)

  ┌────────────────────────────────────────────────────────────┐
  │ "use client"  komponent + barcha import'i CLIENT (cascade) │
  │  chegara PASTGA (faqat interaktiv barg — yuqoriga emas)     │
  └────────────────────────────────────────────────────────────┘

   "use client" — komponent + import'lariga tarqaladi (bir marta yozsang — pastga cascade)
   Yuqoriga qo'yma (layout/page) — butun daraxt client bo'ladi (Server afzalligi yo'qoladi)

"use client" chegarasi — eng nozik va eng ko'p xato qilinadigan tushuncha. "use client" komponentga + uning barcha import'lariga tarqaladi (cascade — pastga oqadi): agar Dashboard.tsxga "use client" qo'ysangiz va u Chart, utilsni import qilsa — Chart va utils ham Client'da ishlaydi (ular ham client modullar bo'ladi). Ya'ni "use client" — bir "chegara" (boundary) belgilaydi: undan pastdagi hamma narsa (import qilingan komponentlar, funksiyalar) client. Tuzoq: "use client"ni juda yuqoriga qo'yish — masalan app/layout.tsxga (root layout) "use client" qo'ysangiz, butun ilova Client bo'ladi (Server Components'ning barcha foydasi — tezlik, xavfsizlik, kam JavaScript — yo'qoladi!). To'g'ri yo'l — "use client"ni faqat kerakli (interaktiv) komponentga, eng pastga qo'yish (2.4 — chegarani barglarga yaqin). Ikki nuqta: (1) "use client" — komponent + import'lariga tarqaladi (cascade — bir marta yozsangiz, pastga oqadi); (2) uni yuqoriga qo'yma (layout/page — butun daraxt client bo'ladi, Server afzalligi yo'qoladi) — faqat interaktiv bargga. Bu — Next.js'da eng keng performance xatosi: "use client"ni yuqoriga qo'yib, butun ilovani client qilib qo'yish (SPA'dek — Server'ning foydasisiz). To'g'ri strategiya — minimal client chegarasi (faqat interaktiv qismlar).

2.7. children naqshi — server'ni client ichida uzatish

text
  MUAMMO: Client Component ichida Server Component kerak (lekin to'g'ridan import yo'q — 2.5)

  YECHIM: Server'ni CLIENT'ga CHILDREN (yoki props) orqali uzat:

  // app/page.tsx (Server) — server komponentni children sifatida uzatadi:
  import ClientWrapper from "./ClientWrapper";   // Client
  import ServerContent from "./ServerContent";   // Server

  export default function Page() {
    return (
      <ClientWrapper>                {/* Client */}
        <ServerContent />            {/*  Server — children sifatida (Client emas!) */}
      </ClientWrapper>
    );
  }

  // ClientWrapper.tsx (Client)
  "use client";
  export default function ClientWrapper({ children }: { children: React.ReactNode }) {
    const [open, setOpen] = useState(false);   // client interaktivlik
    return <div>{open && children}</div>;       // children (Server) — shu yerga
  }

   children naqshi — Server'ni Client ichida ko'rsatish (Client uni IMPORT qilmaydi — uzatiladi)
   ServerContent SERVER'da qoladi (children — Client uni "joylashtiradi", lekin render — server)

children naqshi — server'ni client ichida uzatish — 2.5'dagi cheklovni (Client server'ni import qila olmaydi) hal qiladi. Muammo: ba'zan Client Component ichida Server Component kerak (masalan interaktiv accordion ichida server'da render bo'lgan kontent), lekin Client server'ni to'g'ridan import qila olmaydi. Yechim — server komponentni Client'ga children (yoki props) orqali uzatish. Misol: app/page.tsx (Server) — <ClientWrapper> (Client) ichida <ServerContent /> (Server) ni children sifatida joylashtiradi. ClientWrapper (Client) esa childrenni oladi va render qiladi ({open && children}). Eng muhim: ServerContent server'da qoladi (render — server'da, ma'lumot server'da) — ClientWrapper uni import qilmaydi (faqat children slot orqali "joylashtiradi"). Ya'ni Client uni qaerga qo'yishni biladi (children), lekin nima ekanini bilmaydi (uni render qilmaydi — server qiladi). Bu — React'ning kompozitsiya falsafasining (11.2: 2.8 children) Next.js Server/Client kontekstidagi qo'llanishi. Ikki nuqta: (1) children naqshi — Server'ni Client ichida ko'rsatish (Client uni import qilmaydi — children orqali uzatiladi); (2) ServerContent server'da qoladi (children — Client uni "joylashtiradi", lekin render server'da). Bu naqsh — interaktiv o'ram (Client) + statik/ma'lumotli ichak (Server) ni birlashtirishning toza usuli (eng keng — Client modal ichida server kontent).

2.8. Ma'lumot uzatish — server client (serializable)

text
  SERVER  CLIENT ma'lumot PROPS orqali (lekin SERIALIZABLE bo'lishi shart):

  // app/page.tsx (Server) — server'da ma'lumot, client'ga props orqali:
  import LikeButton from "./LikeButton";   // Client
  export default async function Page() {
    const product = await db.product.findUnique(...);   // server ma'lumot
    return <LikeButton productId={product.id} likes={product.likes} />;  // props (serializable)
  }

  SERIALIZABLE (server  client props bo'lishi mumkin):
   string, number, boolean, null
   obyekt, massiv (oddiy — JSON kabi)
   Date (Next.js qo'llab-quvvatlaydi)

  NON-SERIALIZABLE (props sifatida O'TMAYDI — xato):
   funksiya (server funksiyasi client'ga props — yo'q; Server Action bundan mustasno — 13.5)
   class instance, Map/Set (oddiy emas)
   Date'dan murakkab obyektlar

   Server  Client props SERIALIZABLE bo'lishi shart (JSON kabi — string/number/obyekt)
   Funksiya props sifatida O'TMAYDI (Server'dan Client'ga — Server Action istisno — 13.5)

Ma'lumot uzatish — server client (serializable) — Server'dan Client'ga ma'lumotni qanday berish. Server Component'dan Client Component'ga ma'lumot props orqali uzatiladi (oddiy React props — 11.2: 2.7). Misol: app/page.tsx (Server) server'da ma'lumot oladi (await db.product...), keyin <LikeButton productId={product.id} likes={product.likes} /> — Client komponentga props sifatida beradi. Lekin muhim cheklov: bu props'lar serializable (JSON kabi — server'dan client'ga "uzatiladigan") bo'lishi shart. Serializable (o'tadi): string, number, boolean, null, oddiy obyekt/massiv (JSON kabi), Date (Next.js qo'llab-quvvatlaydi). Non-serializable (o'tmaydi — xato): funksiya (server funksiyasini client'ga props sifatida berib bo'lmaydi — Server Action bundan mustasno — 13.5), class instance, Map/Set, murakkab obyektlar. Ikki nuqta: (1) Server Client props serializable bo'lishi shart (string/number/oddiy obyekt — JSON'dek; chunki ma'lumot server'dan client'ga "sim orqali" uzatiladi — JSON sifatida); (2) funksiya props sifatida o'tmaydi (Server'dan Client'ga — Server Action istisno — 13.5'da ko'ramiz). Demak Server'da ma'lumot olib (DB), kerakli qismini (id, likes — oddiy qiymatlar) Client'ga props orqali uzatasiz — Client esa interaktivlik (like bosish) qiladi. Bu — server (ma'lumot) + client (interaktivlik) ni bog'lashning standart usuli.

2.9. Server-only kod himoyasi (secrets/DB)

text
  SERVER COMPONENT — secret/DB'ni XAVFSIZ ishlatadi (brauzerga chiqmaydi — 10.11):

  // app/page.tsx (Server) — API kalit server'da (brauzerga YO'Q):
  export default async function Page() {
    const res = await fetch("https://api.example.com/data", {
      headers: { Authorization: `Bearer ${process.env.SECRET_API_KEY}` },  //  secret — server'da
    });
    //  process.env.SECRET_API_KEY brauzerga UMUMAN chiqmaydi (server'da qoladi)
    const data = await res.json();
    return <div>{data.value}</div>;
  }

  QO'SHIMCHA HIMOYA — "server-only" paket:
  import "server-only";   //  bu modul client'ga import qilinsa — BUILD XATOSI (himoya)
  //  xato bilan DB/secret kodini client'ga olib ketishni OLDINI OLADI

  ┌────────────────────────────────────────────────────────────┐
  │ Server Component: secret/DB to'g'ridan (brauzerga chiqmaydi) │
  │ "server-only": client import'ni taqiqlaydi (build xato)     │
  └────────────────────────────────────────────────────────────┘

   Server Component'da secret/API kalit/DB to'g'ridan (brauzerga chiqmaydi — xavfsiz — 10.11)
   "server-only" — DB/secret kodini xato bilan client'ga olib ketishdan himoya (build xato)

Server-only kod himoyasi — Server Components'ning eng katta xavfsizlik afzalligi. Server Component server'da ishlaydi, shuning uchun u secret (API kalit), DB to'g'ridan ulanish, va boshqa maxfiy narsani xavfsiz ishlata oladi — chunki bu kod brauzerga chiqmaydi 10.11-bob. Misol: process.env.SECRET_API_KEYni server'da fetch header'ida ishlatish — bu kalit brauzerga umuman chiqmaydi (server'da qoladi; SPA'da esa har secret brauzerda bo'lardi — xavfli — 11.3: 2.10). Qo'shimcha himoyaserver-only paket: faylga import "server-only" yozsangiz, agar o'sha modul (DB/secret kodi) tasodifan Client Component'ga import qilinsa — build xatosi beradi (himoya). Bu DB so'rovlari yoki secret kodini xato bilan client'ga (brauzerga) olib ketishning oldini oladi (xato erta tutiladi — production'da emas). Ikki nuqta: (1) Server Component'da secret/API kalit/DB to'g'ridan ishlatsa bo'ladi (brauzerga chiqmaydi — xavfsiz — bu SPA'ning katta muammosini hal qiladi); (2) server-only — DB/secret kodini client'ga import qilishni taqiqlaydi (build xato — himoya qatlami). Bu — Next.js'ning full-stack xavfsizligining asosi: backend mantiqi (DB, secret) Server Components'da xavfsiz yashaydi, alohida backend kerak bo'lmasligi mumkin (13.5, 13.6).

2.10. Hydration — server render keyin client jonlanish

text
  HYDRATION — server'da render bo'lgan HTML brauzer'da "JONLANishi" (interaktiv bo'lishi):

  JARAYON (Client Component uchun):
  1. Server — Client Component'ni render qiladi (HTML — statik, lekin interaktiv emas)
  2. HTML brauzerga keladi (foydalanuvchi KO'Radi — tez, lekin tugma hali ishlamaydi)
  3. JavaScript yuklanadi  React "hydrate" qiladi (HTML'ga interaktivlik ulaydi)
  4. Endi tugma/state ishlaydi (komponent "jonlandi")

  ┌────────────────────────────────────────────────────────────┐
  │ Server render (statik HTML)  brauzer (ko'rinadi)           │
  │ JS yuklanadi  hydrate (interaktiv)  jonli                 │
  └────────────────────────────────────────────────────────────┘

  HYDRATION XATOSI — server va client render FARQ qilsa:
   Date.now(), Math.random(), window — server va client'da HAR XIL  "Hydration failed"
   server/client mos kelsin; brauzer-only kod useEffect'da (mount'dan keyin — 11.5)

   Hydration — server HTML'ga client interaktivligini ulash (Client Component "jonlanadi")
   Hydration xato — server/client farq (Date/random/window)  useEffect'da yoki mos qil

Hydration — server render keyin client jonlanish — Next.js'ning nozik, lekin muhim mexanizmi. Hydration — server'da render bo'lgan HTML'ning brauzer'da "jonlanishi" (interaktiv bo'lishi). Client Component uchun jarayon: (1) server Client Component'ni render qiladi (HTML — statik, lekin hali interaktiv emas); (2) HTML brauzerga keladi (foydalanuvchi darrov ko'radi — tez, lekin tugma hali ishlamaydi — faqat ko'rinish); (3) JavaScript yuklanadi va React "hydrate" qiladi (mavjud HTML'ga interaktivlik — event listener, state — ulaydi); (4) endi tugma/state ishlaydi (komponent "jonlandi"). Ya'ni Client Component ham server'da render bo'ladi (HTML — tez ko'rinish, SEO), keyin brauzer'da jonlanadi (interaktivlik). Hydration xatosi — agar server va client render farq qilsa yuzaga keladi: Date.now(), Math.random(), window (server'da yo'q) — bular server'da va client'da har xil natija beradi React "Hydration failed" xatosi (server HTML client bilan mos kelmadi). Yechim: server/client mos kelsin; brauzer-only kodni useEffectda (mount'dan keyin — faqat client'da — 11.5) yoki shartli render. Ikki nuqta: (1) hydration — server HTML'ga client interaktivligini ulash (Client Component server'da render + client'da jonlanish — ikki foyda: tez ko'rinish + interaktivlik); (2) hydration xatosi — server/client farq (Date/random/window) — yechim useEffect yoki mos qilish (13.1: Xato 7). Bu — Next.js'ning SSR + interaktivlik birikmasining ichki mexanizmi.

2.11. 3-tomon komponentlar va best practices

text
  3-TOMON INTERAKTIV KOMPONENT (Framer Motion, react-select — "use client" kerak):
  // Eski kutubxona "use client" yozmagan bo'lsa — o'rab ber:
  // app/components/MotionDiv.tsx
  "use client";
  export { motion } from "framer-motion";   // o'rab, client qiladi 11.16-bob

  yoki to'g'ridan Client Component'da ishlatiladi (u allaqachon client).

  BEST PRACTICES (Server/Client):
   Default Server (faqat interaktivlik  "use client" — 2.4)
   "use client"ni PASTGA surish (barglar — yuqoriga emas — 2.6)
   Server'da ma'lumot (await — useEffect emas — 2.2)
   Server  Client props serializable 2.8-bob
   Client ichida Server  children naqshi 2.7-bob
   Secret/DB Server'da (server-only — 2.9)
   Hydration xatosidan saqlanish (Date/random/window — useEffect — 2.10)

   3-tomon interaktiv  "use client" (o'rab yoki client ichida)
   Server-first: ko'p Server (tez/xavfsiz/yengil) + oz Client (interaktiv barg)

3-tomon komponentlar va best practices — Server/Client'ning amaliy yakuni. 3-tomon interaktiv komponentlar (Framer Motion — 11.16, react-select, chart kutubxonalari) — bular hook/state ishlatadi, shuning uchun Client Component'da bo'lishi kerak. Agar kutubxona o'zi "use client" yozgan bo'lsa (zamonaviy kutubxonalar) — to'g'ridan ishlatsa bo'ladi; aks holda (eski) — uni "use client" faylda o'rab ("use client"; export { motion } from "framer-motion"), yoki Client Component ichida ishlatasiz (u allaqachon client). Best practices (Server/Client — butun bobni umumlashtiradi): (1) default Server (faqat interaktivlik "use client" — 2.4); (2) "use client"ni pastga surish (barglar — yuqoriga emas — 2.6); (3) server'da ma'lumot (awaituseEffect emas — 2.2); (4) Server Client props serializable 2.8-bob; (5) Client ichida Server children naqshi 2.7-bob; (6) secret/DB Server'da (server-only — 2.9); (7) hydration xatosidan saqlanish (Date/random/windowuseEffect — 2.10). Ikki nuqta: (1) 3-tomon interaktiv kutubxona "use client" (o'rab yoki client ichida); (2) server-first falsafa — ko'p Server Component (tez, xavfsiz, yengil) + oz Client Component (interaktiv barg). Bu yakuniy strategiya — Next.js'ning eng katta afzalligini (kam JavaScript, tez, xavfsiz) ro'yobga chiqaradi. Server/Client'ni to'g'ri ishlatish — Next.js dasturchisining eng muhim ko'nikmasi.

2.12. Context va Provider — Client chegarasida

text
  CONTEXT — faqat CLIENT'da (useContext hook — Server'da yo'q — 2.2):

  MUAMMO: React Context 12.1-bob provider'i hook ishlatadi  Client bo'lishi shart,
          lekin butun ilovani (layout) Client qilib qo'yish MUMKIN EMAS (Server foydasi).

  YECHIM: Provider'ni ALOHIDA Client Component'da o'rab, layout'ga (Server) children orqali:

  // app/providers.tsx — CLIENT (faqat provider)
  "use client";
  import { ThemeContext } from "./theme";
  export function Providers({ children }: { children: React.ReactNode }) {
    return <ThemeContext.Provider value={...}>{children}</ThemeContext.Provider>;
  }

  // app/layout.tsx — SERVER (default) — Providers'ni children bilan o'raydi 2.7-bob:
  import { Providers } from "./providers";
  export default function RootLayout({ children }) {
    return <html><body><Providers>{children}</Providers></body></html>;
  }

   Context provider — CLIENT (hook); lekin uni ALOHIDA o'rab, layout SERVER qoladi (children)
   Provider ostidagi Server children — SERVER'da qoladi (Provider ularni faqat "o'raydi")

Context va Provider — Client chegarasida — React Context'ni (12.1 — global holat) Next.js App Router'da to'g'ri ishlatish. Muammo: Context Provider createContext + useContext ishlatadi (hook), demak u Client Component bo'lishi shart (2.2 — Server'da hook yo'q). Lekin agar provider'ni to'g'ridan root layout.tsxga qo'ysangiz, layout'ga "use client" kerak bo'lardi — va u holda butun ilova Client bo'lardi (2.6 — Server Components foydasi yo'qoladi). Yechim — provider'ni alohida Client Component'da (app/providers.tsx"use client") o'rab, uni layout.tsx (Server — default) ichida children bilan chaqirish (2.7 — donut naqshi). Bu ishlaydi, chunki Providers — Client (context beradi), lekin uning ichidagi {children} (butun sahifa daraxti) Server'da qoladi (Provider ularni faqat "o'raydi", import qilmaydi — 2.7). Ikki nuqta: (1) context provider — Client (hook), lekin uni alohida faylda o'rab, layout Server qoldiriladi (children orqali); (2) provider ostidagi Server children Server'da qoladi (faqat Client komponentlar useContext bilan o'qiy oladi). Demak global holat (theme, auth, savat — 12) provider'i Client chegarasida yashaydi, lekin ilovaning qolgan qismi Server-first bo'lib qoladi.

2.13. "use server" va Server Actions — client'dan server'ga

text
  "use client" 2.3-bob — komponent BRAUZER'da;  "use server" — funksiya SERVER'da:

  ┌───────────────────────────┬──────────────────────────────────┐
  │ "use client" (fayl/tepa)  │ "use server" (funksiya/fayl tepa)  │
  │  komponent CLIENT bo'ladi │  funksiya SERVER'da ishlaydi      │
  │ (state, hodisa, hook)     │ (Server Action — DB, secret)       │
  └───────────────────────────┴──────────────────────────────────┘

  // app/actions.ts
  "use server";                          //  bu fayl funksiyalari — Server Action
  export async function createPost(formData: FormData) {
    await db.post.create({ data: { title: formData.get("title") as string } });
  }

  // Client Component Server Action'ni PROPS/import orqali chaqira oladi (istisno — 2.8):
  // <form action={createPost}> ...   funksiya, lekin Server Action bo'lgani uchun O'TADI

   "use server" — funksiya server'da ishlasin (Server Action); "use client"ning teskarisi
   Server Action — Client'dan server'ga funksiya chaqirish ko'prigi (2.8'dagi funksiya istisnosi)

"use server" va Server Actions — client'dan server'ga"use client"ning "juftligi" va 2.8'dagi funksiya cheklovining istisnosi. "use client" 2.3-bob komponentni brauzer'da ishlatadi; "use server" esa aksincha — funksiyani server'da ishlatadi (Server Action). Faylning tepasiga (yoki funksiya ichiga) "use server" yozilsa, o'sha funksiya Server Action bo'ladi: u server'da ishlaydi, shuning uchun DB/secret'ga to'g'ridan kira oladi 2.9-bob, lekin uni Client Component'dan chaqirsa bo'ladi (masalan <form action={createPost}>). Bu — 2.8'dagi muhim istisno: odatda funksiya Server Client props sifatida o'tmaydi (non-serializable), lekin Server Action bundan mustasno — Next.js uni maxsus "server'ga chaqiruv" (RPC — masofaviy funksiya chaqiruvi) sifatida uzatadi. Ikki nuqta: (1) "use server" — funksiyani server'da ishlatadi (Server Action), "use client"ning teskarisi (biri komponent uchun, biri funksiya uchun); (2) Server Action — Client'dan server'ga funksiya chaqirish "ko'prigi" (form yuborish, ma'lumot yozish — useEffect+fetch+API route'siz). To'liq mavzu — **13.5-bob (Data fetching va Server Actions)**da chuqur ochiladi; bu yerda faqat "use client" bilan bog'liq juftlik sifatida eslatildi.

2.14. RSC payload, client-only, va App Router chegarasi

text
  RSC PAYLOAD — Server Component NATIJASI qanday brauzerga keladi:

  Server Component render  RSC PAYLOAD (maxsus, JSON'ga o'xshash format):
   Server Component'lar HTML/daraxt sifatida (JavaScript'siz)
   Client Component'lar uchun "joy" (placeholder) + qaysi JS bundle kerakligi
   props (serializable — 2.8) shu payload ichida
  Brauzer bu payload'ni o'qiydi  HTML ko'rsatadi  Client qismlarni hydrate qiladi 2.10-bob

  client-only PAKET — "server-only"ning 2.9-bob teskarisi:
  import "client-only";   //  bu modul SERVER'ga import qilinsa — BUILD XATOSI
  //  brauzer-only kod (window ishlatadigan) server'da ishlashining oldini oladi

   MUHIM: Server/Client Components — FAQAT App Router'da (Pages Router'da YO'Q!)
   Pages Router (eski — pages/): hamma komponent client (getServerSideProps alohida)
   App Router (app/) — bu bobning hammasi shu yerda

   RSC payload — Server natijasini brauzerga uzatish formati (HTML + Client "joy" + props)
   Server/Client Components faqat App Router'da (Pages Router'da bu model yo'q)

RSC payload, client-only, va App Router chegarasi — mexanizm va muhim chegaralar. RSC payload: Server Component brauzerga oddiy HTML emas, balki RSC payload (React Server Components uchun maxsus, JSON'ga o'xshash "sim formati") sifatida uzatiladi. Bu payload ichida: (1) Server Component'larning render natijasi — element daraxti (ularning JavaScript'isiz — 2.2); (2) Client Component'lar uchun "joy" (placeholder) + qaysi JS bundle'ni yuklash kerakligi belgisi; (3) Server'dan Client'ga uzatilgan props (serializable bo'lishi shart aynan shuning uchun — 2.8: payload ichida "sim orqali" ketadi). Brauzer bu payload'ni o'qib, HTML'ni ko'rsatadi, so'ng Client qismlarni hydrate qiladi 2.10-bob. client-only paketserver-onlyning 2.9-bob teskarisi: import "client-only" yozilgan modul agar tasodifan Server Component'ga import qilinsa, build xatosi beradi — bu brauzer-only kod (window, localStorage ishlatadigan) server'da ishlab, "window is not defined" (Xato 6) berishining oldini oladi. Eng muhim chegara: Server/Client Components modeli faqat App Router'da (app/ papka) mavjud — eski Pages Router'da (pages/ papka) bu yo'q (u yerda hamma komponent client, ma'lumot esa getServerSideProps/getStaticProps orqali alohida olinadi). Ikki nuqta: (1) RSC payload — Server natijasini brauzerga uzatish formati (Server HTML/daraxt + Client "joy" + serializable props); (2) bu butun model faqat App Router'da — Pages Router'da Server/Client Components tushunchasi mavjud emas. Bu bobning hamma narsasi App Router (app/) uchun.


3. Sintaksis — tez ma'lumotnoma

text
SERVER 2.2-bob:      export default async function Page() { const d = await db... }  (default)
CLIENT 2.3-bob:      "use client";  +  useState/onClick (interaktivlik)
QAROR 2.4-bob:       ma'lumot/statik  Server; interaktivlik (state/hodisa)  Client
KOMPOZITSIYA 2.5-bob:Server  Client import OK; Client  Server import YO'Q
CHEGARA 2.6-bob:     "use client"  komponent + import'lari (pastga surish — yuqoriga emas)
CHILDREN 2.7-bob:    <ClientWrapper><ServerContent/></ClientWrapper>  (Server children sifatida)
PROPS 2.8-bob:       Server  Client props SERIALIZABLE (string/number/obyekt; funksiya YO'Q)
SECRET 2.9-bob:      Server'da process.env.SECRET (brauzerga yo'q); import "server-only"
HYDRATION 2.10-bob:  server HTML  client jonlanish; Date/random/window  useEffect
CONTEXT 2.12-bob:    provider CLIENT (alohida o'ram) + layout SERVER (children)
USE SERVER 2.13-bob: "use server"  Server Action (client'dan server'ga funksiya — 13.5)
RSC/ROUTER 2.14-bob: RSC payload (Server  brauzer); "client-only"; FAQAT App Router

4. Batafsil kod namunalari

Har misol: Maqsad + izohli kod + "Bu kod nima qiladi".

Misol 1 — Server Component (ma'lumot — 2.2)

Maqsad: Server Component'ning asosiy kuchini ko'rsatish — server'da ma'lumotlar bazasidan to'g'ridan ma'lumot olish, hech qanday useEffect/useState/loading'siz. Bu 11.5'dagi butun fetch og'rig'ini yo'qotadi.

tsx
// app/products/page.tsx — Server Component (default — "use client" YO'Q)
import { db } from "@/lib/db";   // Prisma client 6.12-bob — server'da

export default async function ProductsPage() {
  //  DB'dan TO'G'RIDAN (server'da — brauzep'da mumkin emas edi):
  const products = await db.product.findMany({
    orderBy: { createdAt: "desc" },   // eng yangi birinchi
  });

  // Ma'lumot TAYYOR — to'g'ridan render (loading holati KERAK EMAS):
  return (
    <ul>
      {products.map((p) => (
        <li key={p.id}>{p.name} — {p.price} so'm</li>
      ))}
    </ul>
  );
}

Bu kod nima qiladi: Bu — Server Component (App Router'da default — "use client" yo'q). Komponent async (server'da asinxron ishlaydi), shuning uchun u ma'lumotlar bazasidan to'g'ridan ma'lumot ola oladi: await db.product.findMany() (Prisma ORM — 6.12 — server'da ishlaydi). Bu SPA'da mumkin emas edi — brauzer'da DB'ga to'g'ridan ulanish xavfli va ishlamas edi (shuning uchun SPA'da API qatlami + useEffect + useState + loading kerak edi — 11.5). Next.js Server Component'da esa: (1) komponent server'da ishlaydi DB'ga to'g'ridan kirish bor; (2) await bilan ma'lumotni kutadi (loading holati kerak emas — server ma'lumot kelguncha kutadi, keyin HTML render qiladi); (3) ma'lumot tayyor holda to'g'ridan .map() (11.5'dagi useEffect/useState/isLoading/race — butun og'riq yo'qoladi). Natijada: kod 5 baravar qisqa, ma'lumot server'da (xavfsiz, tez), va HTML ichida keladi (Google ko'radi — SEO). Bu — Next.js'ning eng katta "wow" momenti: server'da ma'lumot = soddaroq + tezroq + xavfsizroq.

Misol 2 — Client Component (interaktivlik — 2.3)

Maqsad: Interaktivlik kerak bo'lganda Client Component'ni qanday qilishni ko'rsatish — "use client" direktivasi va useState/onClick. Bu Server Component qila olmaydigan narsani (interaktivlik) beradi.

tsx
// app/components/Counter.tsx
"use client";   //  MUHIM: bu fayl client (interaktivlik uchun — Server'da useState yo'q)

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);   // state — faqat client'da (server'da yo'q — 2.2)

  return (
    <div>
      <p>Hisob: {count}</p>
      {/* onClick — interaktivlik (hodisa — brauzep kerak) */}
      <button onClick={() => setCount(count - 1)}>-</button>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  );
}

Bu kod nima qiladi: Bu — Client Component (interaktivlik uchun). Faylning eng tepasiga "use client" yozilgan — bu Next.js'ga "bu komponent brauzer'da ishlasin" deydi. Nega kerak: bu komponent useState (holat — 11.4) va onClick (hodisa — 11.4: 2.10) ishlatadi — bular interaktivlik (foydalanuvchi tugma bosganda son o'zgaradi), va interaktivlik faqat brauzer'da mumkin (Server Component'da useState/onClick ishlamaydi — server brauzer emas — 2.2). "use client"siz, bu komponent Server Component bo'lardi va useState xato berardi ("only works in a Client Component" — 13.1: Xato 1). Demak "use client" — "bu komponent (va u import qilgan narsalar — 2.6) interaktiv, brauzer'da jonlansin" degan signal. Bu komponent avval server'da render bo'ladi (HTML — <p>Hisob: 0</p> — tez ko'rinish), keyin brauzer'da hydrate bo'ladi (JavaScript ulanadi — tugma ishlay boshlaydi — 2.10). Eslatma: "use client" faqat kerakli (interaktiv) komponentga — bu yerda Counter interaktiv, shuning uchun client mantiqli 2.4-bob.

Misol 3 — Server + Client kompozitsiya (eng keng naqsh — 2.5)

Maqsad: Eng keng Next.js naqshini ko'rsatish — Server Component (ma'lumot, statik) ichida Client Component (interaktiv barg). Bu "server-first" strategiyaning amaliy ko'rinishi.

tsx
// app/products/[id]/page.tsx — SERVER Component (ma'lumot, statik)
import { db } from "@/lib/db";
import AddToCartButton from "./AddToCartButton";   // Client Component (import — 2.5)

export default async function ProductPage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  const product = await db.product.findUnique({ where: { id } });   // server ma'lumot

  if (!product) return <p>Mahsulot topilmadi</p>;

  return (
    <main>
      {/* SERVER — statik, SEO (ma'lumot HTML ichida): */}
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      <p className="price">{product.price} so'm</p>

      {/* CLIENT — interaktiv barg (server ichida — props orqali ma'lumot — 2.8): */}
      <AddToCartButton productId={product.id} />
    </main>
  );
}

Bu kod nima qiladi: Bu — Next.js'ning eng muhim amaliy naqshi (server-first arxitektura). ProductPageServer Component (ma'lumotni server'da DB'dan oladi, statik kontentni render qiladi). Uning ichida <AddToCartButton />Client Component (interaktiv "Savatga qo'sh" tugmasi). Ya'ni: sahifaning katta qismi (sarlavha, tavsif, narx) server'da render bo'ladi — bu ma'lumot (DB'dan), SEO (Google bu kontentni HTML ichida ko'radi), va tez (server tayyor HTML beradi). Faqat kichik interaktiv qism (tugma — bosilganda savatga qo'shadi) Client Component ("use client" — interaktivlik kerak). Server Component Client'ni import qila oladi (2.5 — import AddToCartButton) va uni render qiladi — bu ishlaydi (Next.js Client uchun joy zaxiralab, brauzer'da jonlantiradi). productId Client'ga props orqali uzatiladi (serializable — string — 2.8). Bu naqsh natijasi: minimal JavaScript brauzerga (faqat tugma kodi — sarlavha/tavsif JavaScript'i yo'q), maksimal server render (tez, SEO, xavfsiz). Demak default hamma narsa Server, faqat interaktiv barglar (tugma, forma) Client — bu Next.js'ning "server-first" falsafasining amaliy timsoli.

Misol 4 — children naqshi (Client ichida Server — 2.7)

Maqsad: Client Component ichida Server Component ko'rsatish — children naqshini ko'rsatish. Bu interaktiv o'ram (Client) + ma'lumotli ichak (Server) ni birlashtirishning usuli.

tsx
// app/components/Collapsible.tsx — CLIENT (interaktiv o'ram)
"use client";
import { useState } from "react";

export default function Collapsible({ children }: { children: React.ReactNode }) {
  const [open, setOpen] = useState(false);   // client interaktivlik (ochiq/yopiq)
  return (
    <div>
      <button onClick={() => setOpen(!open)}>{open ? "Yopish" : "Ochish"}</button>
      {open && <div>{children}</div>}        {/*  children — bu yerga Server kontent keladi */}
    </div>
  );
}

// app/page.tsx — SERVER (children sifatida Server kontent uzatadi)
import Collapsible from "./components/Collapsible";   // Client
import { db } from "@/lib/db";

export default async function Page() {
  const data = await db.content.findFirst();   // server ma'lumot
  return (
    <Collapsible>                  {/* Client o'ram */}
      {/*  Bu — SERVER kontent (children — Client uni IMPORT qilmaydi, joylashtiradi): */}
      <article>{data?.text}</article>
    </Collapsible>
  );
}

Bu kod nima qiladi: Bu — children naqshi (2.7 — Client ichida Server). Muammo: Collapsible — Client Component (interaktiv — ochiq/yopiq toggle), va uning ichida server'da olingan ma'lumot (data.text) ko'rsatish kerak. Lekin Client Component server komponentni to'g'ridan import qila olmaydi 2.5-bob. Yechim — children: Collapsible (Client) children prop'ini oladi va uni render qiladi ({open && children}). page.tsx (Server) esa <Collapsible> ichiga server kontentni (<article>{data.text}</article> — ma'lumot server'dan) joylashtiradi. Eng muhim: <article>{data.text}</article>server'da render bo'ladi (ma'lumot server'dan, JavaScript brauzerga yo'q), Collapsible esa uni faqat children slot orqali "joylashtiradi" (uni import qilmaydi, render qilmaydi — faqat qaerga qo'yishni biladi). Ya'ni Client (Collapsible) interaktivlik (toggle) beradi, Server kontent (article) ma'lumot va statik render beradi — ikkalasi birlashadi, lekin har biri o'z muhitida (Client — brauzer, Server — server). Bu naqsh — interaktiv o'ram + statik/ma'lumotli ichak (modal, accordion, tab ichida server kontent) — Next.js'dagi juda keng va kuchli naqsh. children'siz, butun article Client bo'lardi (ma'lumot brauzerda olinar edi — sekinroq).

Misol 5 — Server'da secret (xavfsizlik — 2.9)

Maqsad: Server Component'ning xavfsizlik afzalligini ko'rsatish — API kalit (secret)ni server'da ishlatish, brauzerga chiqarmacdan. Bu SPA'ning katta muammosini (secret brauzerda — 11.3: 2.10) hal qiladi.

tsx
// app/dashboard/page.tsx — Server Component
import "server-only";   //  bu fayl FAQAT server'da (client import qilca — build xato — 2.9)

export default async function DashboardPage() {
  //  SECRET API KALIT server'da (brauzepga UMUMAN chiqmaydi):
  const res = await fetch("https://api.payment.com/stats", {
    headers: {
      Authorization: `Bearer ${process.env.PAYMENT_SECRET_KEY}`,   // server'da qoladi
    },
  });
  const stats = await res.json();

  return (
    <div>
      <h1>To'lov statistikasi</h1>
      <p>Jami: {stats.total} so'm</p>
    </div>
  );
}

Bu kod nima qiladi: Bu — Server Component'ning xavfsizlik kuchini ko'rsatadi. process.env.PAYMENT_SECRET_KEY — to'lov tizimining maxfiy API kaliti (juda nozik — sizib ketsa, pul o'g'irlanishi mumkin). Bu kalit fetch header'ida ishlatiladi (to'lov API'siga so'rov), va eng muhimi — brauzerga umuman chiqmaydi (chunki bu kod server'da ishlaydi — Server Component). SPA'da (11.3: 2.10) esa har secret brauzerda bo'lardi (VITE_ — faqat public bo'lishi kerak edi, secret backend'da qolishi kerak edi — alohida server) — Next.js Server Component'da esa secret to'g'ridan ishlatsa bo'ladi (server'da, xavfsiz). import "server-only" — qo'shimcha himoya: agar bu fayl (secret kodi) tasodifan Client Component'ga import qilinsa, build xatosi beradi (kod brauzerga olib ketilmaydi — xato erta tutiladi, production'da emas). Demak: Server Component secret/DB/maxfiy logikani xavfsiz ishlata oladi (brauzerga chiqmaydi), va server-only bu himoyani mustahkamlaydi. Bu — Next.js'ning full-stack xavfsizligining asosi: backend mantiqi (to'lov, DB, secret) Server Components'da yashaydi (alohida backend server kerak bo'lmasligi mumkin — 13.5).

Misol 6 — "use client" chegarasini pastga suyish (2.6)

Maqsad: "use client"ni to'g'ri joyga (pastga — interaktiv bargga) qo'yishni ko'rsatish — yuqoriga qo'yish xatosini (butun ilova client) va to'g'ri yo'lni taqqoslash. Bu eng keng performance xatosin oldini oladi.

tsx
//  NOTO'G'RI — "use client" YUQORIDA (butun sahifa client — Server foydasi yo'q):
// "use client";    buni page.tsx'ga qo'ysang — butun sahifa + ma'lumot client (sekin!)

//  TO'G'RI — sahifa Server, faqat interaktiv qism Client:
// app/page.tsx — SERVER (ma'lumot, statik)
import SearchBar from "./SearchBar";   // Client (faqat qidiruv interaktiv)

export default async function Page() {
  const products = await db.product.findMany();   // server ma'lumot (JS brauzepga yo'q)
  return (
    <div>
      <h1>Mahsulotlar</h1>           {/* server — statik */}
      <SearchBar />                  {/*  FAQAT bu client (interaktiv qidiruv) */}
      <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>   {/* server — ro'yxat */}
    </div>
  );
}

// app/SearchBar.tsx — CLIENT (faqat qidiruv — kichik chegapa)
"use client";
import { useState } from "react";
export default function SearchBar() {
  const [query, setQuery] = useState("");
  return <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Qidirish" />;
}

Bu kod nima qiladi: Bu — "use client" chegarasining eng muhim amaliy darsi 2.6-bob. Noto'g'ri yo'l: "use client"ni page.tsxning tepasiga qo'ysangiz — butun sahifa (sarlavha, ma'lumot olish, ro'yxat) client bo'ladi — bu Server Components'ning barcha foydasini (server ma'lumot, kam JavaScript, SEO) yo'qotadi, va ilova SPA'dek sekin bo'ladi. To'g'ri yo'l: page.tsx — Server Component (ma'lumotni server'da oladi, statik kontentni render qiladi — JavaScript brauzerga yo'q), va faqat interaktiv qism (SearchBar — qidiruv input'i) Client Component ("use client" — kichik chegara). Ya'ni "use client"ni pastga suyab — faqat haqiqatan interaktiv komponentga (SearchBar) — qo'yasiz, sahifaning qolgan qismi Server. Natijada: faqat SearchBarning JavaScript'i brauzerga yuboriladi (kichik), sarlavha/ro'yxat JavaScript'i yo'q (faqat HTML — yengil, tez). Agar "use client"ni yuqoriga qo'yilsa, butun sahifa JavaScript'i brauzerga borardi (katta, sekin). Demak: chegarani barglarga yaqin tutish kerak (interaktiv komponent — pastda), butun daraxtni client qilmaslik lozim (yuqorida). Bu — Next.js performance'ining eng muhim qoidasi: minimal client chegarasi = minimal JavaScript = tez ilova.

Misol 7 — Server'da fetch + Client'ga props (2.8)

Maqsad: Server'da ma'lumot olib, uni Client Component'ga serializable props orqali uzatishni ko'rsatish. Bu server (ma'lumot) + client (interaktivlik) ni bog'lashning standart usuli.

tsx
// app/post/[id]/page.tsx — SERVER (ma'lumot oladi)
import LikeButton from "./LikeButton";   // Client

export default async function PostPage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  const post = await db.post.findUnique({ where: { id } });   // server ma'lumot

  return (
    <article>
      <h1>{post?.title}</h1>
      <p>{post?.content}</p>
      {/*  Server ma'lumotini Client'ga PROPS orqali (serializable — 2.8): */}
      <LikeButton postId={post!.id} initialLikes={post!.likes} />
    </article>
  );
}

// app/post/[id]/LikeButton.tsx — CLIENT (interaktiv — like bosish)
"use client";
import { useState } from "react";
export default function LikeButton({ postId, initialLikes }: { postId: string; initialLikes: number }) {
  const [likes, setLikes] = useState(initialLikes);   // server'dan kelgan boshlang'ich qiymat
  async function handleLike() {
    setLikes(likes + 1);                               // optimistic (darrov UI)
    await fetch(`/api/posts/${postId}/like`, { method: "POST" });   // server'ga (13.6)
  }
  return <button onClick={handleLike}> {likes}</button>;
}

Bu kod nima qiladi: Bu — server (ma'lumot) va client (interaktivlik) ni bog'lashning standart usuli 2.8-bob. PostPage (Server) post ma'lumotini DB'dan oladi (await db.post...), va kerakli qismini (post.id, post.likes) <LikeButton> (Client)ga props orqali uzatadi. Bu props'lar serializable (postId — string, initialLikes — number — JSON kabi, server'dan client'ga "sim orqali" uzatiladigan — 2.8). LikeButton (Client) esa interaktivlik beradi: useState(initialLikes) (server'dan kelgan boshlang'ich qiymat bilan boshlaydi), onClick (like bosilganda darrov son oshadi — optimistic — 12.4: 2.10, va server'ga so'rov yuboriladi). Demak: server post kontentini render qiladi (sarlavha, matn — SEO, tez) va boshlang'ich ma'lumotni (likes soni) beradi; client faqat interaktivlik (like bosish — son o'zgarishi) qiladi. initialLikes props — server'dan client'ga ma'lumot "ko'prigi" (server biladi necha like bor, client undan boshlaydi). Eslatma: agar funksiyani props sifatida bermoqchi bo'lsangiz (masalan server funksiyasini), bu ishlamaydi (non-serializable — 2.8) — Server Action bundan istisno 13.5-bob. Bu naqsh — har "ma'lumot + interaktivlik" holatida (like, savat, izoh) ishlatiladi.

Misol 8 — Hydration xatosidan saqlanish (2.10)

Maqsad: Hydration xatosinng keng sababini (server/client farq — Date, window) va uni qanday tuzatishni ko'rsatish. Bu Next.js'da keng uchraydigan, chalkash xato.

tsx
"use client";
import { useState, useEffect } from "react";

export default function CurrentTime() {
  //  NOTO'G'RI — server va client'da HAR XIL vaqt (hydration xato):
  // return <p>{new Date().toLocaleTimeString()}</p>;   // server: 10:00:00, client: 10:00:01  XATO

  //  TO'G'RI — brauzep-only qiymat useEffect'da (mount'dan keyin — faqat client):
  const [time, setTime] = useState<string | null>(null);

  useEffect(() => {
    // useEffect FAQAT client'da ishlaydi (mount'dan keyin — server'da emas):
    setTime(new Date().toLocaleTimeString());          // endi faqat client'da
    const id = setInterval(() => setTime(new Date().toLocaleTimeString()), 1000);
    return () => clearInterval(id);                    // cleanup (11.5: 2.7)
  }, []);

  // Boshlang'ich render (server va client BIR XIL — null  hydration mos):
  return <p>Vaqt: {time ?? "yuklanmoqda..."}</p>;
}

Bu kod nima qiladi: Bu — hydration xatosin 2.10-bob keng sababini va yechimini ko'rsatadi. Muammo: agar komponent server'da va client'da har xil natija bersa (masalan new Date() — server'da render bo'lganda 10:00:00, brauzer'da hydrate bo'lganda 10:00:01 — bir soniya farq), React "Hydration failed" xatosini beradi (server HTML client render bilan mos kelmadi). Bu Date.now(), Math.random(), window/localStorage (server'da yo'q) bilan tez-tez yuzaga keladi. Yechim: brauzer-only qiymatni useEffectda olish — useEffect faqat client'da ishlaydi (mount'dan keyin — server'da umuman ishlamaydi — 11.5). Demak: boshlang'ich render'da time = null (server va client'da bir xil"yuklanmoqda..." — hydration mos keladi); keyin useEffect (faqat client'da) timeni haqiqiy vaqtga o'rnatadi (setTime(...)). Natijada: server va client boshlang'ich render bir xil (null — hydration muvaffaqiyatli), keyin client'da vaqt paydo bo'ladi (faqat brauzer'da). Bu — har "brauzer-only" qiymat (vaqt, random, window o'lchami, localStorage) uchun naqsh: boshlang'ich null/default (server-client mos), keyin useEffectda haqiqiy qiymat (faqat client). Hydration xatosi — Next.js'da eng chalkash xatolardan biri; bu naqsh uni hal qiladi.

Misol 9 — Server Component'da 3-tomon kutubxona (markdown — 2.2)

Maqsad: Server Component'ning yana bir afzalligini ko'rsatish — katta kutubxona (markdown render)ni server'da ishlatish, uni brauzerga yubormasdan. Bu bundle'ni kichik tutadi.

tsx
// app/blog/[slug]/page.tsx — SERVER Component
import { marked } from "marked";   // markdown  HTML kutubxonasi (katta)

export default async function BlogPostPage({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params;
  const post = await db.post.findUnique({ where: { slug } });

  //  marked (katta kutubxona) SERVER'da ishlaydi — brauzepga YUBORILMAYDI:
  const html = marked(post?.markdown ?? "");   // markdown'ni HTML'ga (server'da)

  return (
    <article>
      <h1>{post?.title}</h1>
      {/* Server'da render qilingan HTML (marked'ning JS'i brauzepga yo'q): */}
      <div dangerouslySetInnerHTML={{ __html: html }} />
    </article>
  );
}

Bu kod nima qiladi: Bu — Server Component'ning yana bir muhim afzalligini ko'rsatadi (kam JavaScript — 2.2). marked — markdown matnini HTML'ga aylantiruvchi kutubxona (nisbatan katta). Bu komponent Server Component bo'lganligi uchun, marked server'da ishlaydi (const html = marked(post.markdown) — server'da markdown HTML), va markedning JavaScript kodi brauzerga umuman yuborilmaydi (faqat natija — tayyor HTML — brauzerga keladi). SPA'da (yoki Client Component'da) esa marked brauzerga yuborilardi (katta JavaScript — bundle oshadi, sekinroq) — chunki markdown brauzer'da render bo'lardi. Next.js Server Component'da: katta kutubxona (markdown, syntax highlighter, sana formatlovchi) server'da ishlaydi, brauzer faqat natijani (HTML) oladi. Bu — bundle'ni kichik tutishning kuchli usuli: og'ir kutubxonalar (faqat ma'lumotni qayta ishlash uchun — interaktiv emas) Server Component'da qoladi (brauzerga yuborilmaydi). Demak Server Component'ning afzalliklari: ma'lumot (Misol 1), xavfsizlik (Misol 5), va kam JavaScript (bu misol — og'ir kutubxonani server'da saqlash). Bu — "server'da nima qilinsa, brauzer o'shancha yengil" tamoyili.

Misol 10 — To'liq naqsh (server + client + children — 2.5, 2.7)

Maqsad: Server, Client, va children naqshini birga ko'rsatish — to'liq, real Next.js sahifa strukturasi. Bu butun bobning amaliy yakuni.

tsx
// app/dashboard/page.tsx — SERVER (ma'lumot, asosiy struktura)
import { db } from "@/lib/db";
import StatsCard from "./StatsCard";        // Server (statik)
import RefreshButton from "./RefreshButton"; // Client (interaktiv)
import Tabs from "./Tabs";                   // Client (o'ram)

export default async function DashboardPage() {
  const stats = await db.stats.findFirst();   // server ma'lumot (xavfsiz, tez)

  return (
    <main>
      <header>
        <h1>Dashboard</h1>            {/* server — statik */}
        <RefreshButton />            {/* client — interaktiv tugma */}
      </header>

      {/* Server kartalar (ma'lumot, JS brauzepga yo'q): */}
      <div className="grid">
        <StatsCard title="Foydalanuvchilar" value={stats?.users ?? 0} />
        <StatsCard title="Daromad" value={stats?.revenue ?? 0} />
      </div>

      {/* Client o'ram (Tabs — interaktiv) ichida SERVER kontent (children — 2.7): */}
      <Tabs>
        {/* Bu — server'da render bo'ladi (ma'lumot), Tabs faqat joylashtiradi: */}
        <section>{stats?.summary}</section>
      </Tabs>
    </main>
  );
}

Bu kod nima qiladi: Bu — Server/Client/children naqshlarining to'liq, real ko'rinishi (butun bobning yakuni). DashboardPageServer Component (ma'lumotni DB'dan oladi, asosiy strukturani render qiladi). Ichida uch xil komponent: (1) StatsCard — Server Component (statik kartalar — ma'lumot ko'rsatadi, interaktivlik yo'q — JavaScript brauzerga yo'q, tez); (2) RefreshButton — Client Component (interaktiv tugma — bosilganda ma'lumotni yangilaydi — "use client"); (3) Tabs — Client Component (interaktiv o'ram — tab almashtirish), va uning ichida server kontent (<section>{stats.summary}</section> — children naqshi — 2.7 — server'da render, Tabs faqat joylashtiradi). Demak butun sahifa strukturasi: server-first (ko'p qism Server — sarlavha, kartalar, kontent — ma'lumot, SEO, tez, yengil), faqat interaktiv barglar Client (RefreshButton — tugma, Tabs — o'ram). Va Client o'ram (Tabs) ichida Server kontent (children orqali — JavaScript brauzerga yo'q). Bu — Next.js'ning to'g'ri arxitektura naqshi: minimal client (faqat interaktivlik), maksimal server (ma'lumot, statik), va children bilan ularni nafis birlashtirish. Natija: tez (server render), xavfsiz (server'da ma'lumot), va yengil (minimal JavaScript). Bu naqshni o'zlashtirish — Next.js dasturchisi bo'lishning asosiy ko'nikmasi.


5. To'g'ri va noto'g'ri holatlar

1) Komponent turi

text
 hamma narsaga "use client" (SPA'dek — Server foydasi yo'q — 2.6)
 default Server; faqat interaktiv  "use client" (2.4)

2) "use client" joyi

text
 layout/page'ga "use client" (butun daraxt client — 2.6)
 interaktiv bargga (pastga surish — Misol 6)

3) Client ichida Server

text
 Client Component'da Server'ni import (ishlamaydi — 2.5)
 children naqshi (Server children sifatida — 2.7, Misol 4)

4) Props

text
 funksiyani ServerClient props (non-serializable — 2.8)
 string/number/obyekt (serializable); funksiya — Server Action (13.5)

5) Ma'lumot

text
 Server Component'da useEffect+fetch (server'da useEffect yo'q)
 async + await (to'g'ridan — Misol 1, 2.2)

6) Brauzer-only

text
 Date.now()/window render'da (hydration xato — 2.10)
 useEffect'da (faqat client — Misol 8)

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — You're importing a component that needs useState. It only works in a Client Component

Sababi: Server Component'da hook 2.2-bob. Yechimi: faylga "use client" (Misol 2).

Xato 2 — Hydration failed because the initial UI does not match

Sababi: server/client render farq (Date/random/window — 2.10). Yechimi: brauzer-only kod useEffectda (Misol 8).

Xato 3 — Functions cannot be passed directly to Client Components

Sababi: funksiya props sifatida ServerClient (non-serializable — 2.8). Yechimi: serializable props; yoki Server Action 13.5-bob.

Xato 4 — Butun ilova sekin (Server foydasi yo'q)

Sababi: "use client" juda yuqorida 2.6-bob. Yechimi: chegarani pastga surish (interaktiv barg — Misol 6).

Xato 5 — Client Component'da DB/secret ishlamaydi

Sababi: Client'da server kodi (DB, secret — 2.9). Yechimi: DB/secret Server Component'da; client'ga props yoki Server Action.

Xato 6 — window is not defined

Sababi: Server Component yoki render'da window (server'da yo'q). Yechimi: "use client" + useEffect (faqat brauzer — 2.10).

Xato 7 — Server Component'da onClick ishlamaydi

Sababi: Server'da interaktivlik yo'q 2.2-bob. Yechimi: interaktiv qismni Client Component'ga ("use client").

Xato 8 — async/await is not yet supported in Client Components

Sababi: Client Component async bo'la olmaydi (faqat Server Component async — 2.2). Yechimi: ma'lumotni Server Component'da await bilan olib, Client'ga props orqali uzatiladi (2.8, Misol 7); yoki Client'da useEffect+fetch 11.5-bob.

Xato 9 — useContext/provider Server Component'da ishlamaydi

Sababi: Context hook — faqat Client'da 2.12-bob. Yechimi: provider'ni alohida "use client" faylda o'rab, layout (Server) ichida children bilan chaqiriladi 2.12-bob.


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • React (11-QISM): Server/Client — React komponentlari, lekin qaerda ishlashi farq.
  • Hooks 11.5-bob: hooklar faqat Client Component'da (Server'da yo'q).
  • Data fetching 13.5-bob: Server Component async fetch (Server Actions — funksiya istisno).
  • Routing 13.2-bob: page/layout — Server Component (default).
  • Rendering 13.4-bob: Server Component — SSR/SSG asosi.
  • Xavfsizlik (10.11, 14): Server'da secret (brauzerga yo'q).
  • Performance 11.11-bob: kam JavaScript (Server Component — yengil bundle).
  • Context/Zustand (12): client state — Client Component'da.

8. Eng yaxshi amaliyotlar (best practices)

  • Default Server (faqat interaktivlik "use client" — 2.4).
  • "use client" pastga (interaktiv barg — yuqoriga emas — 2.6).
  • Server'da ma'lumot (await — useEffect emas — 2.2, Misol 1).
  • Client ichida Server children (2.7, Misol 4).
  • Props serializable (string/number/obyekt — 2.8).
  • Secret/DB Server'da (server-only — 2.9, Misol 5).
  • Og'ir kutubxona Server'da (markdown — kam JS — Misol 9).
  • Hydration xatosidan saqlanish (Date/window useEffect — 2.10, Misol 8).
  • Server-first (ko'p Server + oz Client — 2.11).
  • 3-tomon interaktiv "use client" (o'rab — 2.11).

9. Amaliy loyiha: "Server-First Blog"

Server/Client'ni to'g'ri ishlatishni real blogda mustahkamlash.

Maqsad

Blog qur: server'da ma'lumot (post, markdown), client interaktivlik (like, izoh) — to'g'ri server/client ajratish bilan.

Talablar (requirements)

  1. Server post sahifasi: DB'dan post + markdown render (Server — Misol 1, 9).
  2. Client like tugmasi: interaktiv (Server post ichida — Misol 3, 7).
  3. Props: server'dan client'ga serializable (postId, likes — Misol 7).
  4. children naqshi: Client o'ram (Collapsible) ichida Server kontent (Misol 4).
  5. Secret: server'da API kalit (brauzerga yo'q — Misol 5).
  6. "use client" pastda: chegarani barglarga (Misol 6).
  7. Hydration: brauzer-only (vaqt/random) — useEffect (Misol 8).
  8. server-only: DB/secret faylda (Misol 5).
  9. Active link: navbar (usePathname — 13.2).
  10. Server-first: ko'p Server, oz Client (audit qil — qaysi nega).

Maslahatlar (hint)

  • Default Server; interaktivlik "use client" (Xato 1).
  • "use client" pastga (butun sahifa emas — Misol 6).
  • Client ichida Server children (Xato 3 — funksiya emas).
  • Hydration useEffect (Date/window — Xato 2).
  • Secret Server'da + server-only (Misol 5).

"Tayyor" mezonlari (acceptance criteria)

  • Server post sahifasi (ma'lumot + markdown).
  • Client like (Server ichida).
  • Serializable props.
  • children naqshi (Client ichida Server).
  • Secret server'da (brauzerga yo'q).
  • "use client" minimal (barglar).
  • Hydration xato yo'q.
  • Server-first (ko'p Server audit).

Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.


10. Xulosa va keyingi bobga ko'prik

Bu bobda Next.js'ning eng muhim tushunchasini — Server vs Client Components — chuqur o'rgandik:

  • Muammo (kod qaerda — 2.1); Server Components (default, foydalar — 2.2); Client Components ("use client" — 2.3); qaror 2.4-bob.
  • Kompozitsiya (ServerClient — 2.5); "use client" chegarasi (cascade — 2.6); children naqshi 2.7-bob; props serializable 2.8-bob.
  • Secret himoya 2.9-bob; hydration 2.10-bob; 3-tomon va best practices 2.11-bob.
  • Context/provider (Client chegarasi — 2.12); "use server" (Server Actions ko'prigi — 2.13); RSC payload / client-only / App Router chegarasi 2.14-bob.

Endi siz Next.js'ning yuragini — qaysi komponent server'da, qaysi client'da ishlashini, ular qanday birlashishini, ma'lumot qanday uzatilishini — bilasiz. "Server-first" strategiya (ko'p Server, oz Client) — tez, xavfsiz, yengil ilova kalitidir.

Keyingi bob — 13.4-bob: Rendering — SSR, SSG, ISR, CSR. Server Components'ni bildik; endi Next.js sahifani qachon va qanday render qilishini — to'rt strategiyani — chuqur o'rganamiz: SSR (har so'rovda server — dinamik), SSG (build paytida — statik, eng tez), ISR (SSG + davriy yangilash — statik tezlik + yangilanish), CSR (brauzer — interaktiv). Har birini qachon ishlatish, qanday belgilash (dynamic, revalidate), va kontentga mos strategiya tanlash. Bu — Next.js'ning tezlik va yangilanish balansin kaliti.


Foydalanilgan rasmiy/ishonchli manbalar

  • Next.js rasmiy hujjati (nextjs.org/docs) — "Server Components", "Client Components", "Composition Patterns", "Server and Client Composition Patterns"
  • Next.js rasmiy hujjati — "Rendering: How Server and Client Components render"; "App Router vs Pages Router" (bu model faqat App Router'da — 2.14)
  • React rasmiy hujjati (react.dev) — "Server Components", "'use client'" direktivasi, "'use server'" direktivasi; "Passing props to a Client Component"
  • React RFC — "React Server Components" (RSC dizayni va payload formati — 2.14)
  • Next.js rasmiy hujjati — "Data Security" (server-only, client-only, taint API — 2.9, 2.14); "Hydration" va hydration xatolari (2.10)
  • Next.js rasmiy hujjati — "Server Actions and Mutations" ("use server" — 2.13, 13.5-bob)
  • Vercel muhandislik blogi — "Understanding React Server Components"; RSC payload va streaming rendering mexanizmi

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
13.3-bob: Server Components vs Client Components — Wisar