This error occurs when you try to render a JavaScript object or array directly as a React child. React expects primitive values (strings, numbers) or valid React elements, not plain objects or unserializable data structures.
React children must be serializable values like strings, numbers, or React components. When you attempt to render a JavaScript object, array, Date, Promise, or any non-serializable value directly in JSX, React cannot convert it to DOM content and throws this error. This is a type safety mechanism that catches common mistakes where developers forget to extract specific properties or map over arrays before rendering.
Look at the error message in your browser console. It will show the component name and line number where the invalid object was rendered. The error message may also display 'object with keys {key1, key2}' to help identify what object is being rendered.
Example error:
Error: Objects are not valid as a React child (found: object with keys {id, name}). If you meant to render a collection of children, use an array instead.If you're rendering an object, access the specific property you want to display instead of the entire object.
Before:
const user = { id: 1, name: 'John', email: '[email protected]' };
return <div>{user}</div>; // Error!After:
const user = { id: 1, name: 'John', email: '[email protected]' };
return <div>{user.name}</div>; // Works!When you have an array of objects, use the .map() method to render each item as a React element.
Before:
const items = [{id: 1, text: 'Apple'}, {id: 2, text: 'Banana'}];
return <ul>{items}</ul>; // Error!After:
const items = [{id: 1, text: 'Apple'}, {id: 2, text: 'Banana'}];
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
); // Works!Date objects must be converted to a string representation before rendering.
Before:
const date = new Date();
return <p>Today is {date}</p>; // Error!After:
const date = new Date();
return <p>Today is {date.toLocaleDateString()}</p>; // Works!
// Or use toISOString(), toString(), etc.Using double curly braces {{}} creates an object literal, which is not valid as a child. Use single braces {} for variable interpolation.
Before:
const message = 'Hello';
return <div>{{message}}</div>; // Error!After:
const message = 'Hello';
return <div>{message}</div>; // Works!Note: Double braces are only valid when passing inline styles:
return <div style={{ color: 'red' }}>{message}</div>; // OK - style prop expects an objectNever render a Promise or async function result directly. Use useEffect or event handlers to resolve the Promise first.
Before:
const fetchData = async () => {
return await fetch('/api/data');
};
return <div>{fetchData()}</div>; // Error! fetchData returns a PromiseAfter:
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
const response = await fetch('/api/data');
const result = await response.json();
setData(result);
};
fetchData();
}, []);
return <div>{data ? data.message : 'Loading...'}</div>; // Works!Object.keys() and Object.values() return arrays, which need to be mapped to render individual items.
Before:
const user = { name: 'John', age: 30 };
return <div>{Object.keys(user)}</div>; // Error!After:
const user = { name: 'John', age: 30 };
return (
<div>
{Object.keys(user).map(key => (
<p key={key}>{key}: {user[key]}</p>
))}
</div>
); // Works!In TypeScript projects, you can prevent this error at compile time by using proper typing. Ensure your component's children prop is typed as ReactNode, ReactElement, or a similar valid type. For complex data structures, consider using the Fragment component (<>) to wrap multiple children, or separate your data rendering logic into helper functions that explicitly map objects to React elements.
When working with third-party libraries that return objects (like some API response wrappers), check the library documentation for the correct way to extract the renderable content. Some libraries may have a .data property, .content property, or similar that contains the actual value meant for rendering.
React's error messages have improved over time. If you see 'object with keys {...}' in the error, that's helpful debugging information—it tells you exactly what object was being rendered. Use this to trace back to the parent component that passed that object as a child.
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite