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 benneRoute 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