I am setting up a React app with a Rails backend. I am getting the error "Objects are not valid as a React child (found: object with keys {id, name, info, created_at, updated_at}). If you meant to render a collection of children, use an array instead."
This is what my data looks like:
[
{
"id": 1,
"name": "Home Page",
"info": "This little bit of info is being loaded from a Rails
API.",
"created_at": "2018-09-18T16:39:22.184Z",
"updated_at": "2018-09-18T16:39:22.184Z"
}
]
My code is as follows:
import React from 'react';
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
homes: []
};
}
componentDidMount() {
fetch('http://localhost:3000/api/homes')
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
homes: result
});
},
// error handler
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
const { error, isLoaded, homes } = this.state;
if (error) {
return (
<div className="col">
Error: {error.message}
</div>
);
} else if (!isLoaded) {
return (
<div className="col">
Loading...
</div>
);
} else {
return (
<div className="col">
<h1>Mi Casa</h1>
<p>This is my house y'all!</p>
<p>Stuff: {homes}</p>
</div>
);
}
}
}
export default Home;
What am I doing wrong?
This question is related to
javascript
arrays
reactjs
Had the same error but with a different scenario. I had my state as
this.state = {
date: new Date()
}
so when I was asking it in my Class Component I had
p>Date = {this.state.date}</p>
Instead of
p>Date = {this.state.date.toLocaleDateString()}</p>
In JavaScript, arrays and collections are different, although they are somewhat similar, but here the react needs an array.
You need to create an array
from the collection
and apply it.
let homeArray = new Array(homes.length);
let i = 0
for (var key in homes) {
homeArray[i] = homes[key];
i = i + 1;
}
I had this issue when I was trying to render an object on a child component that was receiving props.
I fixed this when I realized that my code was trying to render an object and not the object key's value that I was trying to render.
Although not specific to the answer, this error mostly occurs when you mistakenly using a JavaScript expression inside a JavaScript context using {}
For example
let x=5;
export default function App(){ return( {x} ); };
Correct way to do this would be
let x=5;
export default function App(){ return( x ); };
I hope it will help someone else.
This error seems to occur also when you UNintentionally send an object to React child components.
Example of it is passing to child component new Date('....') as follows:
const data = {name: 'ABC', startDate: new Date('2011-11-11')}
...
<GenInfo params={data}/>
If you send it as value of a child component parameter you would be sending a complex Object and you may get the same error as stated above.
Check if you are passing something similar (that generates Object under the hood).
I faced same issue but now i am happy to resolve this issue.
npm i core-js
index.js
file.
import core-js
I had a similar error while I was creating a custom modal.
const CustomModal = (visible, modalText, modalHeader) => {}
Problem was that I didn't wrap my values to curly brackets like this.
const CustomModal = ({visible, modalText, modalHeader}) => {}
If you have multiple values to pass to the component, you should use curly brackets around it.
In your state, home is initialized as an array
homes: []
In your return, there is an attempt to render home (which is an array).
<p>Stuff: {homes}</p>
Cannot be done this way --- If you want to render it, you need to render an array into each single item. For example: using map()
Ex: {home.map(item=>item)}
In My case, I had a added async at app.js like shown below.
const App = async() => {
return(
<Text>Hello world</Text>
)
}
But it was not necessary, when testing something I had added it and it was no longer required. After removing it, as shown below, things started working.
const App =() => {
return(
<Text>Hello world</Text>
)
}
Well in my case the data which I wanted to render contained an Object inside that of the array so due to this it was giving error, so for other people out there please check your data also once and if it contains an object, you need to convert it to array to print all of its values or if you need a specific value then use.
My data :
body: " d fvsdv"
photo: "http://res.cloudinary.com/imvr7/image/upload/v1591563988/hhanfhiyalwnv231oweg.png"
postedby: {_id: "5edbf948cdfafc4e38e74081", name: "vit"} //this is the object I am talking about.
title: "c sx "
__v: 0
_id: "5edd56d7e64a9e58acfd499f"
proto: Object
To Print only a single value
<h5>{item.postedby.name}</h5>
I also occured the error,and I sloved it by removing the curly braces,hope it will help someone else.
You can see that ,I did not put the con in the curly brace,and the error occured ,when I remove the burly brace , the error disappeared.
const modal = (props) => {
const { show, onClose } = props;
let con = <div className="modal" onClick={onClose}>
{props.children}
</div>;
return show === true ? (
{con}
) : (
<div>hello</div>
);
There are an article about the usage of the curly brace.click here
Just to add to the other options, I was trying to access a nested object within the main object through the dot method as in:
this.state.arrayData.CompleteAdress.Location
In this case Location is a nested object inside Complete address which is why i cant simply access it with the dot notation.
I got the same error today but with a different scenario as compared to the scenario posted in this question. Hope the solution to below scenario helps someone.
The render
function below is sufficient to understand my scenario and solution:
render() {
let orderDetails = null;
if(this.props.loading){
orderDetails = <Spinner />;
}
if(this.props.orders.length == 0){
orderDetails = null;
}
orderDetails = (
<div>
{
this.props.orders.map(order => (
<Order
key={order.id}
ingredient={order.ingredients}
price={order.price} />
))
}
</div>
);
return orderDetails;
}
In above code snippet : If return orderDetails
is sent as return {orderDetails}
then the error posted in this question pops up despite the value of 'orderDetails' (value as <Spinner/>
or null
or JSX related to <Order />
component).
Error description : react-dom.development.js:57 Uncaught Invariant Violation: Objects are not valid as a React child (found: object with keys {orderDetails}). If you meant to render a collection of children, use an array instead.
We cannot return a JavaScript object from a return call inside the render() method. The reason being React expects a component or some JSX or null to render in the UI and not some JavaScript object that I am trying to render when I use return {orderDetails}
and hence get the error as above.
Had the same issue, In my case I had 1. Parse the string into Json 2. Ensure that when I render my view does not try to display the whole object, but object.value
data = [
{
"id": 1,
"name": "Home Page",
"info": "This little bit of info is being loaded from a Rails
API.",
"created_at": "2018-09-18T16:39:22.184Z",
"updated_at": "2018-09-18T16:39:22.184Z"
}];
var jsonData = JSON.parse(data)
Then my view
return (
<View style={styles.container}>
<FlatList
data={jsonData}
renderItem={({ item }) => <Item title={item.name} />}
keyExtractor={item => item.id}
/>
</View>);
Because I'm using an array, I used flat list to display, and ensured I work with object.value, not object otherwise you'll get the same issue
Source: Stackoverflow.com