When you try to render an object directly in JSX, React throws an error because objects aren’t valid as React children. Here’s how to properly display object content in your components.
The Problem
function UserProfile() {
const user = { name: "John", age: 30 };
return (
<div>
{user} {/* ❌ Error: Objects are not valid as React child */}
</div>
);
}
Solutions
1. Use JSON.stringify()
(Basic Solution)
function UserProfile() {
const user = { name: "John", age: 30 };
return (
<div>
{JSON.stringify(user)} {/* ✅ Works */}
</div>
);
}
2. Format with Pretty Printing (Better Readability)
function UserProfile() {
const user = { name: "John", age: 30 };
return (
<div>
<pre>{JSON.stringify(user, null, 2)}</pre> {/* ✅ Formatted */}
</div>
);
}
3. Render Specific Properties (Recommended for UI)
function UserProfile() {
const user = { name: "John", age: 30 };
return (
<div>
<h2>{user.name}</h2> {/* ✅ Access specific properties */}
<p>Age: {user.age}</p>
</div>
);
}
4. Create a Custom Display Component
function ObjectDisplay({ data }) {
return (
<ul>
{Object.entries(data).map(([key, value]) => (
<li key={key}>
<strong>{key}:</strong> {typeof value === 'object'
? <ObjectDisplay data={value} />
: String(value)}
</li>
))}
</ul>
);
}
function UserProfile() {
const user = { name: "John", details: { age: 30, city: "NY" } };
return <ObjectDisplay data={user} />;
}
When to Use Each Approach
JSON.stringify()
– Quick debugging- Pretty Printed JSON – Displaying configuration data
- Specific Properties – Production UI (best for performance)
- Custom Component – Reusable object visualization
Performance Considerations
- Avoid calling
JSON.stringify()
in render for large objects - For frequently updated objects, consider memoization
- Prefer direct property access for production code
TypeScript Version (With Safety Checks)
interface ObjectDisplayProps {
data: Record<string, unknown>;
depth?: number;
}
function ObjectDisplay({ data, depth = 0 }: ObjectDisplayProps) {
if (depth > 3) return <span>[Deep object]</span>;
return (
<ul style={{ marginLeft: `${depth * 15}px` }}>
{Object.entries(data).map(([key, value]) => (
<li key={key}>
<strong>{key}:</strong> {
typeof value === 'object' && value !== null
? <ObjectDisplay data={value as Record<string, unknown>} depth={depth + 1} />
: String(value)
}
</li>
))}
</ul>
);
}
Remember: Direct object rendering is never allowed in JSX. Always convert to strings or access specific properties.