
"Objects are not valid as a React child": cosa significa e le tre cause più comuni
Perché JSX non renderizza direttamente un oggetto, i tre casi reali che lo scatenano (Date, oggetti errore, Map/Set), e come correggere ciascuno.
Renderizzi qualcosa, aspettandoti del testo, e invece ottieni questo crash:
⛔ Errore
Objects are not valid as a React child (found: object with keys {year, month, day}). If you meant to render a collection of children, use an array instead.
L’errore è più utile della media — elenca letteralmente le chiavi dell’oggetto che hai provato a renderizzare, il che di solito basta per individuare subito l’errore. Ecco le tre forme in cui si presenta più spesso.
Perché succede
JSX sa renderizzare stringhe, numeri, array di cose renderizzabili, ed elementi React. Un semplice oggetto JavaScript non è niente di tutto ciò — React non ha un modo definito per trasformare { year: 2026, month: 9 } in testo, quindi invece di indovinare (mostrando silenziosamente [object Object], che è ciò che produrrebbe String(obj)), lancia un errore.
const config = { year: 2026, month: 9, day: 10 };
return <p>{config}</p>; // lancia — React non sa come renderizzare questo oggetto
Causa #1: renderizzare direttamente una Date
function OrderDate({ order }) {
// order.createdAt è un oggetto Date, non una stringa
return <p>{order.createdAt}</p>;
}
Una Date è un oggetto, non una stringa — va sempre formattata prima:
function OrderDate({ order }) {
return <p>{order.createdAt.toLocaleDateString()}</p>;
}
Se stai già formattando date in tutta l’app, questo è anche esattamente il caso d’uso per Temporal.PlainDate/ZonedDateTime, che ti obbliga a chiamare esplicitamente .toString() o un formatter invece di passare in giro l’oggetto grezzo per errore.
Causa #2: renderizzare l’intero oggetto errore invece del suo messaggio
Molto comune in un blocco catch o nella fallback UI di un error boundary:
try {
await submitForm(data);
} catch (error) {
setError(error); // memorizza l'intero oggetto Error
}
// più avanti, nel render:
return <p>{error}</p>; // lancia — un'istanza di Error è un oggetto
La correzione è renderizzare il messaggio, non l’oggetto errore stesso:
return <p>{error.message}</p>;
Se stai costruendo la fallback UI per un errore di render catturato invece che un errore async catturato, vale la stessa regola dentro componentDidCatch/getDerivedStateFromError di un error boundary.
Causa #3: renderizzare una Map o un Set
const tags = new Map([
["js", "JavaScript"],
["ts", "TypeScript"],
]);
return <p>{tags}</p>; // lancia
Né Map né Set sono array, quindi JSX non sa come iterarli per te. Converti prima esplicitamente:
return (
<ul>
{Array.from(tags.values()).map((tag) => (
<li key={tag}>{tag}</li>
))}
</ul>
);
Perché gli array vanno bene, ma gli oggetti no
Vale la pena notare l’asimmetria, perché confonde spesso — un array di elementi si renderizza senza problemi:
<ul>{[<li key="1">A</li>, <li key="2">B</li>]}</ul> // funziona perfettamente
React supporta esplicitamente gli array di children. La distinzione non è “oggetti vs primitivi,” è “React ha una regola di rendering definita per questa forma.” Gli array di elementi renderizzabili ce l’hanno; i semplici oggetti dati no.
FAQ
❓ Perché React non chiama semplicemente toString() sull'oggetto automaticamente?
Deliberatamente non lo fa, perché produrrebbe di solito silenziosamente [object Object] — una UI
che sembra rotta senza nessun errore a spiegare perché. Lanciare un errore invece fa emergere
subito lo sbaglio, in sviluppo, invece di spedire un bug confuso in produzione.
❓ Vale anche per i React Server Components?
Sì — un Server Component non può comunque renderizzare un oggetto grezzo come child, per lo stesso motivo. Dove cambia leggermente è passare le props tra componenti: le props inviate da un Server Component a un Client Component devono essere serializzabili, un vincolo correlato ma separato da cosa può apparire come contenuto JSX renderizzato.
❓ React 19 ha cambiato questo messaggio d'errore?
La regola di fondo è invariata, ma React 19 ha migliorato la chiarezza del messaggio — le versioni precedenti a volte mostravano una descrizione meno specifica dell’oggetto. Il consiglio sopra vale per qualsiasi versione recente di React.
Conclusione
“Objects are not valid as a React child” è JSX che ti dice di aver trovato un oggetto semplice dove si aspettava testo o elementi renderizzabili — quasi sempre una Date, un intero oggetto errore, o una Map/Set da convertire prima. Il messaggio d’errore stesso, che elenca le chiavi dell’oggetto, di solito basta per puntarti direttamente al valore incriminato.
Riferimenti

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