"Objects are not valid as a React child" means React tried to render a plain JavaScript object (like {} or {name: "John"}) where it expected text, numbers, or elements.
What "Objects are not valid as a React child" Means
React's renderer can only display primitives (strings, numbers, booleans) or React elements. When you pass a plain object directly into JSX — like {user} or {data} — React throws this error because it doesn't know how to convert a key-value map into visible DOM content. The error typically appears in the browser console during development, not at compile time.
Why It Happens
The two most common causes are:
- Rendering an object variable directly: You have
const user = {name: "Suhail"}and write{user}inside JSX instead of{user.name}. - API responses passed straight to JSX: You fetch data, store the entire response object in state, and render it without extracting the fields you need.
Both cases boil down to the same thing: React sees a JavaScript object where it needs a renderable value.
Example Code That Triggers It
import { useState, useEffect } from "react";
export default function UserProfile() {
const [user, setUser] = useState<{name: string} | null>(null);
useEffect(() => {
fetch("/api/user")
.then(res => res.json())
.then(data => setUser(data));
}, []);
// ❌ This throws "Objects are not valid as a React child"
return <div>{user}</div>;
}
If user is {name: "Suhail"}, React tries to render that object directly — and fails with the exact error.
How to Fix It
// ✅ Extract the primitive value you need
return <div>{user ? user.name : "Loading..."}</div>;
// Or use Object.entries() to render all keys
return (
<div>
{user && Object.entries(user).map(([key, value]) => (
<p key={key}>{key}: {value}</p>
))}
</div>
);
The fix works because you're now passing a string (user.name) or an array of elements — both of which React can render natively. The conditional (user ? ... : ...) also handles the null state before data loads.
Common Mistakes That Cause This
- Forgetting to destructure API responses: You write
setUser(response.data)instead ofsetUser(response.data.name). The state now holds an object, and any render of that state breaks. - Rendering arrays of objects without mapping: You return
{items}whereitemsis[{id: 1}, {id: 2}]. The array itself is fine, but each object inside needs to be converted to JSX via.map().
Both mistakes share a pattern — treating structured data as if it were display-ready.
When Should You Worry About This?
You should worry when this error appears after a successful render, not during initial load. If your app renders fine then throws after a fetch completes, your state is being set to an object that JSX can't handle. That's a data-shape bug — fix it by mapping over the object's keys or extracting specific properties. If it appears only during development with HMR (hot module replacement), a stale state from a previous edit can trigger it; a full page refresh usually clears that.
Next time this error appears, check the first line of your JSX return statement — that's where the offending object is almost always sitting.