React
StrictMode: perché gli effect partono due volte
In sviluppo StrictMode monta, smonta e rimonta ogni componente per verificare il cleanup: se l'effect parte due volte, manca una pulizia.
In sintesi
- StrictMode raddoppia solo in sviluppo il montaggio, per far emergere cleanup mancanti.
- In produzione l'effect di mount gira una volta sola: il doppio non è un bug.
- Un effect con fetch ha bisogno di un AbortController, o la risposta arriva due volte.
StrictMode raddoppia il montaggio degli effect solo in sviluppo, per costringere ogni effect a smontarsi bene: se il secondo giro rompe qualcosa, il cleanup manca.
Cosa fa esattamente
React 19 monta il componente, esegue l'effect, lo smonta eseguendo la funzione di cleanup e lo rimonta. Nessuna riga del tuo codice è cambiata: il doppio giro è una prova, non una modifica al comportamento atteso. In produzione il ciclo avviene una volta.
L'effect che regge la prova
useEffect(() => {
const controller = new AbortController();
fetch("/api/projects", { signal: controller.signal })
.then((response) => response.json())
.then(setProjects)
.catch((error) => {
if (error.name !== "AbortError") console.error(error);
});
return () => controller.abort();
}, []);
Al primo smontaggio abort() annulla la richiesta in volo; il secondo montaggio ne avvia una nuova. Senza cleanup la prima risposta scriverebbe sullo stato di un componente già smontato.
I sintomi tipici
- Due richieste: il doppio
POSTin sviluppo è il segnale più frequente di un effect senza guardia. - Listener duplicati:
addEventListenersenzaremoveEventListeneraccumula handler a ogni montaggio. - Timer doppi: un
setIntervalsenzaclearIntervalraddoppia la frequenza dopo il rimontaggio.
Un progetto per provarlo
npm run build
npm run preview
La build di produzione non contiene il doppio montaggio: se il problema sparisce con npm run preview e resta con npm run dev, hai trovato un cleanup mancante.
Record vivi nel catalogo
Tre componenti che leggono una preferenza in un effect al montaggio: theme-toggle, auth-switch e sky-toggle. Per esplorare per categoria parti da 111.985 componenti.
La limitazione
StrictMode verifica che il cleanup esista, non che l'effect sia corretto: un effect con dipendenze sbagliate resta sbagliato anche con il doppio montaggio, e nessun avviso lo segnala. Non sostituisce i test, e in sviluppo può raddoppiare chiamate a servizi esterni che non si possono annullare.
Dove continuare
Cosa cambia in React 19 è in React 19; il confine fra componenti server e hook è in server component e hook; il confronto fra ecosistemi è in Vue 3 vs React.
Domande frequenti
Il doppio effect è un bug di React?
No, è una prova voluta e solo in sviluppo. Serve a far emergere effect senza cleanup, che in produzione causerebbero doppie richieste.
Posso disattivare StrictMode?
Sì, togliendo il wrapper, ma perdi il controllo sui cleanup. Meglio correggere gli effect: la produzione non cambia.
Perché la richiesta parte due volte in sviluppo?
Perché il primo montaggio viene smontato subito e la richiesta non è annullata. Aggiungi un AbortController e il primo giro si ferma.
StrictMode controlla anche i render?
Sì, in sviluppo esegue due volte il corpo del componente e i reducer, per rendere visibili gli effetti collaterali durante il render.
StrictMode vale anche con i Server Component?
No. Il doppio montaggio riguarda il client; i Server Component vengono eseguiti dal server e non hanno effect.