Reputation: 4634
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?
Upvotes: 319
Views: 1250801
Reputation: 71
In my case (Next.js 14) adding a suspense component around the page that is fetching data did the job:
page.tsx:
...
const Home: FC = () => {
return (
<ScrollSnap>
<Suspense>
<Step1Section />
</Suspense>
</ScrollSnap>
...
Step1Section.tsx:
...
import { getItem } from "@/utils/get-item";
const Step1Section: FC = async () => {
const data = await getItem();
...
Although my case would probably be different than yours since in the ScrollSnap component there is a Children.count(props.children)
which is causing the error.
Upvotes: 0
Reputation: 17
I got a same error in starting of my project in react.So i add curly{} braces inside div tag in class rendering.And refresh it,after that i remove that curly braces and again refresh.At that time that error gone and code run successfully.
Upvotes: -2
Reputation: 575
Had the same error but with a different scenario. I had my state as
this.state = {
date: new Date()
}
so when I was calling it in my Class Component I had
p>Date = {this.state.date}</p>
Instead of
p>Date = {this.state.date.toLocaleDateString()}</p>
Upvotes: 2
Reputation: 19
const myObj = {name: 'pkfan'}
<Error status='riase error'> { myObj } </Error>
Above component give error, because (myObj) not valid child.
I accidently pass (Object) instead of (JSX), that's why, I got this error.
solved this after wasting a lot of time.
Upvotes: 1
Reputation: 249
if you want to display all the object without iterating then you must send the data as string value i.e
<p>{variableName.toString()}</>
Upvotes: 6
Reputation: 362
I had a similar problem, I forgot to add curly brackets { }
while accepting the arguments in the component.
I had this: const ServiceCard = (color, title, icon, subtitle) => (
Then I updated it to this: const ServiceCard = ({color, title, icon, subtitle}) => (
and it worked.
Upvotes: 5
Reputation: 503
In my case, I had
<IonListHeader>
<IonLabel>
Order {{index}}
</IonLabel>
</IonListHeader>
instead of
<IonListHeader>
<IonLabel>
Order {index}
</IonLabel>
</IonListHeader>
Double curly braces.
Upvotes: 4
Reputation: 1980
I am using faker.js I was expecting company field to be string but it is an array It was :
<div className='text-gray-400 text-sm'>works at {s.company}</div>
but instead should be
<div className='text-gray-400 text-sm'>works at {s.company.name}</div>
I think it is not programmers fault, world is unexpected place and it's data could be anything. React should point out exact error.
Upvotes: -1
Reputation: 955
I had the same issue then I realized that I made the dumbest mistake ever. I had made my component asynchronous, I mean I used the async keyword, something like this
const ComponentName = async () => {
return <>
<div>This a WRONG component</div>
</>
}
Then after a lot of headaches and prays, I realized my dumb mistake and removed the async.
const ComponentName = () => {
return <>
<div>This a WRONG component</div>
</>
}
Upvotes: 1
Reputation: 749
I had a similar error while I was creating a custom modal.
const CustomModal = (visible, modalText, modalHeader) => {}
Problem was that I forgot that functional components can have only one prop passed to them, according to the REACT documentation:
This function is a valid React component because it accepts a single “props” (which stands for properties) object argument with data and returns a React element. We call such components “function components” because they are literally JavaScript functions. React docs
Therefore when we want to pass several variables we need to wrap them into an object or an Array and pass the pointer to that array or object. And destructure it on the component side before invoking the component. Alternatively we can use curly braces to indicate that we are sending an object with identical property names and variables that contain the value of those properties, like in the example here. And then define the function also to destructure upon arrival of the properties contained in the object.
const CustomModal = ({visible, modalText, modalHeader}) => {}
If you have multiple values to pass to the component, you should pass an object, thus curly brackets around its properties/variables (assuming they have the same name).
Upvotes: 70
Reputation: 169
This error occur to me when send Date object (for example timestamp in firebse) to React child components.
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.
You must send that date as string value
<p>{timestamp.toString()}</p>
should work fine like this.
Upvotes: 8
Reputation: 678
the issue is because you are trying to display the whole object instead of the keys inside the object.
For example: Data is
[
{
"status": "success",
"count": 20511
},
{
"status": "failure",
"count": 1776
}
]
Now, in the component read like below, this will work.
import React, { Component } from 'react';
export default class Display extends Component {
render() {
const { data } = this.props;
return (
<>
{
data.map((value,key)=>
<div>{value.status}</div>
<div>{value.count}</div>
)
}
</>
)
}
}
Upvotes: 9
Reputation: 575
For my case I had
return (
<div >
{updated.map((one) => {
<div>
<h2>{one.name}</h2>
</div>
})}
</div>
);
Then changed to
return (
<div >
{updated.map((one,index) => {
return (
<div key={index}>
<h2>{one.name}</h2>
</div>
)
})}
</div>
);
The issue was that I had no return statement after the map function
Upvotes: 2
Reputation: 1
I had the same issue. In my case, I have not render the value of the item. My initial code was,
keyExtractor={(item, index) => item.id}
data={courseGoals}
renderItem={itemData => (
<View style={styles.listitem}>
<Text>{itemData.item}</Text>
</View>
)}
/>
And I simply added '.value' and it worked!
keyExtractor={(item, index) => item.id}
data={courseGoals}
renderItem={itemData => (
<View style={styles.listitem}>
<Text>{itemData.item.value}</Text>
</View>
)}
/>
Upvotes: 0
Reputation: 41
There is yet another scenerio I captured. I DOM to be rendered was dependent on some checks. So I initialized it with null and on Switch was giving value to it. And while returning just returned that DOM.
export function test() {
let DOM = null;
switch (conditions) {
case 1: {
DOM = <div>SOME DIV</div>;
}
case 2: {
DOM = <div>SOME DIV2</div>;
}
default: {
DOM = null;
}
}
return { DOM }; // -----1 Problem was here
}
Resolution to it was just wrap it with <></>
return <>{DOM}</>
Upvotes: 0
Reputation: 993
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 &&
this.props.orders.length > 0 &&
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 some JSX, false, null, undefined, true 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.
VALID :
<div />
<div></div>
<div>{false}</div>
<div>{null}</div>
<div>{undefined}</div>
<div>{true}</div>
INVALID :
<div>{orderDetails}</div> // This is WRONG, orderDetails is an object and NOT a valid return value that React expects.
Edit: I also got this error on my company's test server used by QA's for their testing. I pointed my local code to that test server and tested the scenario in which this error was reported by QA team and found NO ERROR in my local machine. I got surprised. I re-checked multiple number of times, re-checked the scenario with QA team and I was doing right but still I was not able to replicate the issue. I consulted my fellow devs but still were not able to figure out the root cause. So keeping with the information in the error message I started scanning all the code I had deployed in my last deployment commit ( to be more specific last 4-5 commits because I suspected it could be there from last few deployments but was caught in the current deployment), especially all the components I had developed and found that there was a component - inside which there was no specified condition being met so it was returning NOTHING from it. So see below sample pseudo code. I hope it helps.
render () {
return (
{this.props.condition1 && (
return some jsx 1
)}
{this.props.condition1 && (
return some jsx 2
)})
}
If you see in above pseudo code if condition1 and condition2 are not met then this component will render NOTHING from it and ideally a react component must return some JSX, false, null, undefined, true from it.
Upvotes: 31
Reputation: 486
Same error but a different scenario. I intended to assign my custom functional component to layoutComponent prop of a 3rd party module.
Erroneous code:
customLayout = () => {
// function returning a component
}
//usage:
{customLayout}
Fix:
CustomLayout = () => {
// functional component
}
//usage:
<CustomLayout></CustomLayout>
Upvotes: 0
Reputation: 3095
I had this error when using the BigNumber library on a value before setting to UseState:
const { toBN } = web3.utils;
...
setOwner0Balance(toBN(await getBalance(owner0)));
Upvotes: 0
Reputation: 112
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>
Upvotes: 1
Reputation: 29
I had a similar problem but mine this worked. My output
But the mistake i had done was simple. In my contents wer more than two and i had forgoten to wrap as an array. I had not put carly braces.
import React from 'react'
import {Button} from './Button';
import {Link} from 'react-router-dom'
import './HeroSection.css';
function HeroSection({
lightBg, topLine, lightText, lightTextDesc, headline, description,
buttonLabel, img,alt,imgStart}
) {
return (
<>
<div className={lightBg? 'home__hero-section': 'home__hero-section darkBg'}>
<div className='container'>
<div className="row home__hero-row"
style={{display:'flex', flexDirection:imgStart==='start'?' row-reverse':'row'}}
>
<div className='col'>
<div className='home__hero-text-wrapper'>
<div className='topline'>{topLine}</div>
<h1 className={lightText? 'heading': 'heading dark'}>{headline}</h1>
<p className={lightTextDesc? 'home__hero-subtitle': 'home__hero-subtitle dark'}>
{description}
<Link to='/sign-up'>
<Button buttonSize='btn--wide' buttonColor='blue'>
{buttonLabel}
</Button>
</Link>
</p>
</div>
</div>
<div className='col'>
<div className='home__hero-img-wrapper'>
<img src={img} alt={alt} className='home_hero-img'/>
</div>
</div>
</div>
</div>
</div>
</>
);
}
export default HeroSection
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Upvotes: 0
Reputation: 341
I faced this exact error. On tracing the root cause of this issue, I found that the FRONTEND code (React) is making a call to API and showing the response on the page by accessing some property of that response! So in this case, there are two cases
So we received this error because the React was expecting the STRING but got the object (because you passed Object inside object).
Please check your Backend logic (API) which is sending the response.
Upvotes: 0
Reputation: 2748
I hope it will help someone else.
This error seems to occur also when you UNintentionally send a complex object that includes for example Date 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 complex Object under the hood). Instead you can send that date as string value and do new Date(string_date) in child component.
Upvotes: 15
Reputation: 41
Objects are not valid as a React child
I also got the same error but with different scenario. I was learning react useReducer hook and implemented a counter with increment, decrement and reset buttons and I was trying to display the count on to the screen but I was the above mentioned error.
In the code I had declared the count which is returned by useReducer hook as the object and I was directly trying to return it rather than the count property of it
I should actually return count.count and I was returning count only(object itself) not property.
We can stringify object and return the string also.
import React, { useReducer } from "react";
const initialState = {
count:0,
}
const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return {count:state.count + 1}
case 'decrement':
return {count:state.count - 1}
case 'reset':
return initialState
default:
return state
}
}
function CounterWithReducer(props) {
const [count, dispatch] = useReducer(reducer, initialState);
return (
<>
<h1>{count}</h1>
<button onClick={()=>{dispatch({type:'increment'})}}>Increment</button>
<button onClick={()=>{dispatch({type:"decrement"})}}>Decrement</button>
<button onClick={()=>{dispatch({type:"reset"})}}>Reset</button>
</>
);
}
export default CounterWithReducer;
In the above code
This section (in the return part ) is where I did the mistake instead of count
I need to use count.count
Summary is that if you trying to show object on to screen you can't either use JSON.stringify()
or try to display any property of the object.
I am in early stage of my developer life please pardon me for any spelling mistakes if any.
Upvotes: 4
Reputation: 607
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>
)
}
Upvotes: 2
Reputation: 31
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.
Upvotes: 0
Reputation: 413
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
Upvotes: 2
Reputation: 981
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)}
Upvotes: 1
Reputation: 361
I faced same issue but now i am happy to resolve this issue.
npm i core-js
index.js
file.
import core-js
Upvotes: 0
Reputation: 480
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 ); };
Upvotes: 5
Reputation: 446
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.
Upvotes: 0