I React Server Components (RSC) hanno cambiato radicalmente il modo in cui costruiamo le applicazioni React. Spostando la logica di rendering sul server, possiamo ridurre significativamente il bundle JavaScript inviato al client, portando a tempi di caricamento più rapidi e una migliore esperienza utente. In questo articolo, esploreremo pattern avanzati e best practice per sfruttare gli RSC nel 2026.
Cosa sono i Server Components?
Tradizionalmente, i componenti React venivano renderizzati interamente sul client (CSR) o pre-renderizzati sul server come HTML (SSR) e poi idratati sul client. I Server Components ci permettono di renderizzare i componenti esclusivamente sul server. Il loro codice non viene mai inviato al browser.
I Benefici
- Zero Bundle Size: Le dipendenze usate nei Server Components (come parser markdown o librerie pesanti per le date) rimangono sul server.
- Accesso Diretto al Backend: Puoi interrogare il tuo database direttamente all'interno del componente senza esporre endpoint API.
- Code Splitting Automatico: I componenti client importati lato server vengono automaticamente suddivisi.
Pattern di Data Fetching
Con gli RSC, puoi rendere i tuoi componenti async e attendere i dati direttamente.
// app/users/page.tsx import { db } from '@/lib/db'; export default async function UsersPage() { const users = await db.user.findMany(); return ( <main> <h1>Utenti</h1> <ul> {users.map((user) => ( <li key={user.id}>{user.name}</li> ))} </ul> </main> ); }
Suspense per lo Streaming
Poiché il recupero dei dati può essere lento, avvolgi i tuoi componenti in <Suspense> per mostrare immediatamente un'interfaccia utente di fallback mentre i dati vengono caricati.
import { Suspense } from 'react'; import UserList from './UserList'; import LoadingSkeleton from './LoadingSkeleton'; export default function Page() { return ( <section> <h1>I Miei Utenti</h1> <Suspense fallback={<LoadingSkeleton />}> <UserList /> </Suspense> </section> ); }
Combinare Server e Client Components
Uno degli aspetti più confusi è come combinare componenti Server e Client.
Regola d'oro: I Server Components possono importare Client Components. I Client Components non possono importare direttamente i Server Components. Tuttavia, puoi passare un Server Component come children a un Client Component.
Il Pattern "Children"
// ClientComponent.tsx 'use client'; import { useState } from 'react'; export default function ClientWrapper({ children }) { const [count, setCount] = useState(0); return ( <div onClick={() => setCount((c) => c + 1)}> Conteggio: {count} {children} {/* Questo può essere un Server Component! */} </div> ); }
// ServerPage.tsx import ClientWrapper from './ClientWrapper'; import ServerContent from './ServerContent'; export default function Page() { return ( <ClientWrapper> <ServerContent /> {/* Funziona perfettamente */} </ClientWrapper> ); }
Trappole Comuni
- Usare il Context nei Server Components: Il Context è un concetto lato client. Se devi condividere dati lato server, passali come props o usa una cache specializzata per richiesta.
- Aggiungere Event Handler: Non puoi aggiungere
onClickoonChangea un Server Component. Quella logica appartiene a un nodo foglia generico Client Component.
Conclusione
I React Server Components non sono solo una funzionalità; sono un cambio di paradigma. Comprendendo il confine tra server e client, puoi costruire applicazioni che sono sia altamente interattive che incredibilmente veloci.