Learning
Next.js

Best practice-ek

// ✅ Helyes – Server Component, nincs JS bundle hatás

16. Best practice-ek

Server Componentek preferálása

// ✅ Helyes – Server Component, nincs JS bundle hatás
export default async function ProductList() {
  const products = await db.products.findAll()
  return <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>
}

// ❌ Kerülendő – ugyanez Client Componentként felesleges
'use client'
export default function ProductList() {
  const [products, setProducts] = useState([])
  useEffect(() => {
    fetch('/api/products').then(r => r.json()).then(setProducts)
  }, [])
  // ...
}

Szabály: Ha nincs szükség interaktivitásra, maradj Server Componentnél.

Minimális client JavaScript

A Client Components fa tetején helyezd el a 'use client' határt – ne az egész oldal legyen kliens:

// ✅ Helyes – csak a gomb Client Component
// app/blog/[slug]/page.tsx – Server Component
import { LikeButton } from '@/components/LikeButton' // 'use client' van benne

export default async function BlogPost({ params }) {
  const post = await fetchPost(...)
  return (
    <article>
      <h1>{post.title}</h1>          {/* Server rendered */}
      <div>{post.content}</div>       {/* Server rendered */}
      <LikeButton postId={post.id} /> {/* Csak ez Client */}
    </article>
  )
}

Cache tudatos fejlesztés

// ✅ Helyes – explicit cache, egyértelmű viselkedés
async function getProducts() {
  'use cache'
  cacheLife('hours')
  cacheTag('products')
  return await fetchProducts()
}

// ❌ Kerülendő – rejtett caching logika
const products = await fetch('/api/products') // implicit – ne bízz benne

Route Grouping szervezés

app/
├── (marketing)/          ← marketing oldalak saját layouttal
│   ├── layout.tsx
│   ├── page.tsx
│   └── blog/
├── (dashboard)/          ← autentikált terület saját layouttal
│   ├── layout.tsx        ← auth ellenőrzés itt
│   └── dashboard/
└── (auth)/               ← autentikációs oldalak
    ├── login/
    └── register/

Fetch duplikáció elkerülése

// ✅ Helyes – React automatikusan deduplikálja az azonos fetch kéréseket
async function getUser(id: string) {
  return fetch(`/api/users/${id}`) // ugyanaz a kérés cachelve van egy render alatt
}

// Layout
async function Layout() {
  const user = await getUser('1') // fetch #1
}

// Page
async function Page() {
  const user = await getUser('1') // ugyanaz a cache – nincs dupla kérés
}

Hibakezelés

// app/blog/error.tsx – automatikus error boundary
'use client'

export default function BlogError({
  error,
  reset,
}: {
  error: Error
  reset: () => void
}) {
  return (
    <div className="text-center py-12">
      <h2 className="text-2xl font-bold text-red-600">Hiba történt</h2>
      <p className="text-gray-600 mt-2">{error.message}</p>
      <button
        onClick={reset}
        className="mt-4 px-4 py-2 bg-blue-600 text-white rounded"
      >
        Újrapróbálás
      </button>
    </div>
  )
}

TypeScript szigorú használata

// Típusos params (Next.js 16 async params)
type PageProps = {
  params: Promise<{ slug: string }>
  searchParams: Promise<{ page?: string }>
}

export default async function Page({ params, searchParams }: PageProps) {
  const { slug } = await params
  const { page } = await searchParams
  // ...
}

Minimális props a Client Component felé

A szerverről a kliensre csak szerializálható adat mehet. Ne küldj át függvényeket, class példányokat vagy óriás objektumokat „hátha kell” alapon – növeli a válasz méretét és a hidratálás költségét.

// ✅ Csak ami a gombhoz kell
<LikeButton postId={post.id} initialLikes={post.likeCount} />

// ⚠️ Kerülendő – teljes ORM entitás, felesleges mezőkkel
<LikeButton post={post} />

after() – nem blokkoló háttérfeladatok

Ha válasz után logolás, analytics, cleanup fusson anélkül, hogy megvárnád a befejezését, a Next after API-ja (a dokumentációban leírt importtal) lehetővé teszi, hogy a felhasználói válasz ne lassuljon:

import { after } from 'next/server'

export async function POST(request: Request) {
  await saveOrder(request)
  after(async () => {
    await notifyWarehouse() // a válasz már mehet a kliensnek
  })
  return Response.json({ ok: true })
}

A pontos elérhetőség és import verzió szerint változhat – TypeScript és a projekt Next verziója a döntő.

📝 Összefoglaló – 16. fejezet

  • Mindig Server Component first – csak 'use client'-ot ha tényleg kell
  • A Client Component határt a fa legmélyebbre tedd, ne fentről jelöld
  • Explicit "use cache" direktíva – soha ne bízz az implicit viselkedésben
  • Route groupok szervezési célra, nem routing hatásért
  • TypeScript típusos props – különösen az async params-nál
  • Kevés, szűk props a Client Componentnek; after() háttérmunkára a válasz után

On this page