This error happens when you pass a JavaScript object as a child to an element. The error also can occur when you supply the incorrect element type as the child.
This article takes an in-depth look into practical situations where this invariant error can occur.
Passing JavaScript object as a child to an element
Most HTML elements accept a string or another HTML element as its children. The below examples illustrates attempts to pass JavaScript objects into HTML elements.
As we all know, a UL element accepts <li> elements as children. React generates the invalid object error when we pass the Javascript object (array) items.
const Search = () => {
const items =
[
{id: 1, city:'Oklahoma'},
{id: 2, city:'Edmond'},
{id: 3, city:'Tulsa'},
{id: 4, city:'Toronto'},
{id: 5, city:'Melbourne'}
]
return(
<>
<ul>
{items}
</ul>
</>
)}
The correct way to render <li> items is to iterate the item array and return an <li> element for each item.
<ul>
{items.map((item) => {
return <li key={item.id}>{item.city}</li>
})}
</ul>
Passing an object as <select> element options generates the invalid object error.
const Search = () => {
const items =
[
{id: 1, city:'Oklahoma'},
{id: 2, city:'Edmond'},
{id: 3, city:'Tulsa'},
{id: 4, city:'Toronto'},
{id: 5, city:'Melbourne'}
]
return(
<>
<select>{items}</select>
</>
)}
The correct way to render <select> options is to iterate the item array and return an option element for each item.
<select>
{items.map((item) => {
return <option key={item.id}>{item.city}</option>
})}
</select>
Passing an object as <button> text generates the invalid object error.
const Search = () => {
const items =
[
{id: 1, city:'Oklahoma'},
{id: 2, city:'Edmond'},
{id: 3, city:'Tulsa'},
{id: 4, city:'Toronto'},
{id: 5, city:'Melbourne'}
]
return(
<>
<button>{items}</button>
</>
)}
The correct way to render an array of buttons is to iterate the item array and return a <button> for each item.
{items.map((item) => {
return <button key={item.id}>{item.city}</button>
})}
Passing the wrong component type as a child to an element
Below is an example where <Routes> component accepts <Route> component as a valid child but receives a <Link> instead.
<BrowserRouter>
<Routes>
<Route path="/" element={<Search/>}/>
<Link to="/"/>{/*Wrong component type*/}
</Routes>
</BrowserRouter>