React Server Components spiegati: use client, Server Actions, Suspense | We.Inc
React Server Components spiegati in parole semplici: un diagramma dei confini, le regole di "use client", il recupero dei dati, le server action per i form con useActionState, lo streaming con Suspense e le soluzioni agli errori comuni.
React Server Components spiegati
I React Server Components fanno il render sul server e inviano al browser l'interfaccia finita, non il loro JavaScript. Possono attendere i dati con await e usare direttamente i segreti. Tutto ciò che è interattivo va in un Client Component, un file che inizia con "use client". I form possono chiamare server function marcate "use server", e Suspense invia in streaming più tardi le parti lente.
Le tre direttive e gli hooks che ti servono
Scrivi
Significa
(niente)
Server Component, nell'App Router di Next.js
"use client"
Questo file e i suoi import girano anche nel browser
"use server"
Queste funzioni esportate girano sul server quando vengono chiamate
<Suspense>
Mostra qui un fallback mentre questa parte si carica
Parti dal diagramma: i riquadri blu restano sul server, quelli arancioni arrivano anche al browser. Poi copia i pattern per dati, form e streaming, e usa la tabella degli errori quando la build si lamenta.
Lascia i componenti come Server Components per impostazione predefinita.
Recupera i dati in Server Components asincroni, vicino a dove vengono mostrati.
Aggiungi "use client" solo alle piccole parti che hanno bisogno di stato o gestori di eventi.
Usa le server function per form e modifiche, con useActionState per il feedback.
Racchiudi le parti lente in Suspense, o aggiungi un loading.tsx, così la pagina appare in fretta.
Spingi "use client" il più in basso possibile nell'albero; un confine vicino alla radice rende di nuovo client-side l'intera app.
Valida l'input di ogni server function. È un endpoint pubblico, anche se lo chiama solo il tuo form.
Verifica chi è l'utente dentro ogni server function, non solo nella pagina che mostra il form.
Passa i Server Components ai Client Components come children invece di importarli.
Evita le cascate di richieste: avvia insieme i fetch indipendenti con Promise.all.
Domande frequenti
I Server Components sono la stessa cosa del rendering lato server?
No. Il rendering lato server trasforma qualsiasi componente in HTML per il primo caricamento e invia comunque il suo JavaScript. Un Server Component non invia mai il suo JavaScript, solo il suo output. Anche i Client Components vengono renderizzati sul server per il primo caricamento.
Mi serve Next.js per usare i Server Components?
Serve un framework o un bundler che li supporti. L'App Router di Next.js è il più diffuso; anche alcuni altri, come Waku, li supportano.
Un Client Component può importare un Server Component?
No, un import da un file client porta il modulo nel bundle client. Passa invece il Server Component come children o come altra prop da un genitore che è un Server Component.
Qual è la differenza tra server action e server function?
Oggi React chiama server function qualsiasi funzione marcata "use server". Quando ne usi una come action di un form o la chiami dentro una transition, spesso si parla di server action. Next.js ha usato per primo il termine server action.
useActionState funziona senza JavaScript?
Il form invia comunque i dati alla server function prima dell'hydration, quindi viene inviato. Lo stato di attesa e il messaggio inline richiedono JavaScript, quindi assicurati che il server restituisca in ogni caso una pagina utile.
Perché questo modello aiuta un sito web
La maggior parte di una pagina di marketing o di contenuti non cambia mai dopo il render: titoli, testo, immagini, card dei prodotti. Come Server Components non costano alcun JavaScript, il che lascia il thread principale libero per le poche parti interattive e di solito migliora l'Interaction to Next Paint.
Checklist di sicurezza per le server function
Tratta ogni funzione "use server" come una route API: controlla la sessione, valida l'input con uno schema, verifica che l'utente possa modificare quel record e restituisci solo ciò che serve al client. Non restituire mai righe del database con campi che l'utente non dovrebbe vedere.
Che cosa gira dove
Dove può girare ogni cosa
Ti serve
Server Component
Client Component
Leggere un database o una chiave API segreta
Sì
No (esporrebbe il segreto)
Attendere i dati con await direttamente nel componente
Sì (componente async)
No
useState, useEffect, useReducer
No
Sì
onClick, onChange e altri gestori
No
Sì
window, localStorage, API del browser
No
Sì, dopo il mount
Inviare zero JavaScript per il componente
Sì
No
Renderizzare l'altro tipo
Sì, renderizza Client Components
Solo Server Components passati come children o props
Server e Client Components
Un Server Component che legge i dati
Nell'App Router i componenti sono Server Components salvo indicazione contraria. Possono essere async e parlare direttamente con il database; nulla di questo codice arriva al browser.
Un Client Component per l'interazione
"use client" in cima al file segna un confine: questo file e tutto ciò che importa vengono inclusi nel bundle per il browser. Tieni questi file piccoli e spingili verso le foglie dell'albero.
Passare un Server Component attraverso un Client Component
Un Client Component non può importare un Server Component, ma può riceverne uno come children. Il server lo renderizza prima e il client si limita a posizionare il risultato.
Evita di portare per errore i segreti nel browser
Importare il pacchetto server-only fa fallire la build se un file client importa questo modulo, così una chiave API non può trapelare per un import distratto.
Server function per i form
Un form che invia i dati a una server function
"use server" trasforma una funzione asincrona in un endpoint che il form può chiamare. Il form funziona prima che il JavaScript si carichi, perché è un vero invio di form.
Stato di attesa e risultato con useActionState
useActionState (React 19) avvolge la server function e ti dà il suo ultimo risultato e un flag di attesa, così il pulsante può dire Invio in corso e il messaggio può comparire senza stato aggiuntivo.
Aggiorna i dati della pagina dopo una modifica
Dopo una modifica, indica a Next.js quale percorso ha dati non aggiornati così il render successivo mostra il cambiamento.
Streaming con Suspense
Invia in streaming la parte lenta con Suspense
Racchiudi un Server Component lento in Suspense. Il resto della pagina viene inviato subito con il fallback al suo posto, e la parte lenta arriva in streaming quando i suoi dati sono pronti.
loading.tsx per un'intera route
Un file loading.tsx accanto a page.tsx racchiude per te quella pagina in un confine Suspense, così la navigazione lo mostra subito mentre i dati della pagina si caricano.
Avvia le richieste insieme
Attendere un fetch dopo l'altro in un Server Component somma i loro tempi. Avviali insieme e attendili entrambi.
Errori che incontrerai
Errori comuni e soluzione
Che cosa vedi
Causa
Soluzione
Un hook come useState funziona solo in un Client Component
Un hook in un file senza "use client"
Sposta la parte interattiva in un file a sé che inizia con "use client"
I gestori di eventi non possono essere passati alle props di un Client Component
onClick passato da un Server Component
Metti il gestore dentro il Client Component, oppure passa invece una server function
Le funzioni non possono essere passate direttamente ai Client Components
Una semplice funzione passata come prop oltre il confine
Marcala "use server" se deve girare sul server, oppure definiscila nel file client
Ai Client Components si possono passare solo oggetti semplici
Istanze di classe come modelli pieni di Date o Map inviate come props
Passa dati semplici (stringhe, numeri, array, oggetti semplici)
window is not defined
API del browser usata durante il render sul server
Leggila dentro useEffect, oppure controlla prima typeof window
Hydration mismatch
Server e browser hanno mostrato testo diverso (date, valori casuali)
Mostra la parte che cambia solo sul client, oppure passa il valore dal server