
React 19: "Cannot update a component while rendering a different component"
Cosa significa questo warning, i due pattern che lo scatenano (stato derivato, callback ref), e come spostare l'update fuori dalla fase di render.
A differenza di “Too many re-renders”, questo warning non blocca l’app — compare una volta sola in console, puntando a codice che altrimenti sembra funzionare bene:
⛔ Warning
Cannot update a component (Parent) while rendering a different component (Child). To locate
the bad setState() call inside Child, follow the stack trace as described in
https://react.dev/link/setstate-in-render
È facile ignorarlo perché niente si rompe visibilmente. Non andrebbe ignorato: significa che un componente sta modificando lo stato di un altro componente durante il render, violando la stessa regola di purezza dietro “Too many re-renders” — semplicemente questa volta non genera un loop.
Perché React lo vieta
La fase di render di React dovrebbe essere un calcolo puro: dati props e stato, produce una descrizione della UI, senza side effect. Chiamare setState su un altro componente mentre stai ancora calcolando il tuo output significa che React potrebbe dover buttare via e rifare lavoro già iniziato per quell’altro componente — o peggio, applicare l’update in un ordine incoerente rispetto ad altri update in sospeso. React non può garantire la correttezza in questo scenario, quindi avvisa rumorosamente invece di comportarsi male in silenzio.
Pattern #1: derivare lo stato dalle props senza un effect
Il trigger più comune — un figlio prova a tenere lo stato del genitore “sincronizzato” direttamente durante il proprio render:
function Parent() {
const [selectedId, setSelectedId] = useState(null);
return <Child onFirstRender={setSelectedId} />;
}
function Child({ onFirstRender }) {
// Chiamato durante il render di Child, aggiorna lo stato di Parent — esattamente ciò che scatena il warning
onFirstRender("child-1");
return <div>Child</div>;
}
La correzione è spostare l’update in un effect, che gira dopo che il render è stato committato, non durante:
function Child({ onFirstRender }) {
useEffect(() => {
onFirstRender("child-1");
}, [onFirstRender]);
return <div>Child</div>;
}
💡 Consiglio
Se quello che vuoi davvero è “calcolare un valore derivato dalle props,” spesso non ti serve
affatto useEffect né una callback verso il genitore — basta calcolare il valore direttamente nel
corpo del render (const doubled = props.value * 2) invece di memorizzarlo nello stato e
sincronizzarlo. Usa useEffect specificamente quando devi sincronizzarti con qualcosa esterno a
React (lo stato di un genitore, API del browser, una subscription).
Pattern #2: una callback ref che aggiorna lo stato immediatamente
function Parent() {
const [height, setHeight] = useState(0);
return (
<div ref={(node) => node && setHeight(node.offsetHeight)}>
<Child />
</div>
);
}
Le callback ref girano durante la fase di commit, che è successiva al render — ma se questa specifica ref scatta mentre un componente diverso è ancora a metà del proprio render (un caso comune con componenti annidati e l’ordine di rendering di React), ottieni lo stesso warning. Il pattern più sicuro è memorizzare il nodo in una ref e misurarlo in un effect:
function Parent() {
const [height, setHeight] = useState(0);
const nodeRef = useRef(null);
useEffect(() => {
if (nodeRef.current) setHeight(nodeRef.current.offsetHeight);
}, []);
return (
<div ref={nodeRef}>
<Child />
</div>
);
}
Come leggere lo stack trace che React fornisce
Il warning nomina entrambi i componenti coinvolti — quello il cui stato è stato aggiornato (Parent nel messaggio sopra) e quello che era a metà render quando è successo (Child). Inizia cercando nel sorgente di Child qualsiasi chiamata setState che non sia dentro un event handler o una callback useEffect — molto probabilmente è quella la riga.
FAQ
❓ È lo stesso errore di 'Too many re-renders'?
Sono correlati ma non identici. Entrambi derivano dal chiamare setState durante il render invece
che in un effect o event handler. “Too many re-renders” succede quando l’update colpisce lo
stesso componente che sta renderizzando, creando un loop. Questo warning succede quando
colpisce un componente diverso, il che non genera necessariamente un loop ma è ugualmente
pericoloso.
❓ Posso ignorare questo warning se l'app sembra funzionare?
È rischioso. Il comportamento segnalato non è esplicitamente supportato — potrebbe funzionare oggi e rompersi silenziosamente dopo un aggiornamento di React, o manifestarsi solo come bug sottile sotto il rendering Concurrent, dove il lavoro di render può essere messo in pausa, riavviato, o eseguito due volte.
❓ Succede anche con useReducer?
Sì — dispatch da useReducer scatena lo stesso warning se chiamato durante il render di un
altro componente, per lo stesso identico motivo. La correzione è identica: sposta il dispatch in
un effect o in un event handler.
Conclusione
Questo warning è React che ti protegge da un vero problema di correttezza, non un falso allarme da silenziare. Entrambi i trigger — un figlio che sincronizza lo stato nel genitore durante il render, e una callback ref che scatta nel momento sbagliato — condividono la stessa correzione: spostare l’update in un useEffect o in un event handler, in un punto che gira davvero dopo il render invece che durante.
Riferimenti

Co-Fondatore & CTO presso PAPION. Senior full-stack engineer specializzato in React, TypeScript, Node.js e sicurezza applicativa.