532

In my component's render function I have:

render() {
    const items = ['EN', 'IT', 'FR', 'GR', 'RU'].map((item) => {
      return (<li onClick={this.onItemClick.bind(this, item)} key={item}>{item}</li>);
    });
    return (
      <div>
        ...
                <ul>
                  {items}
                </ul>
         ...
      </div>
    );
  }

everything renders fine, however when clicking the <li> element I receive the following error:

Uncaught Error: Invariant Violation: Objects are not valid as a React child (found: object with keys {dispatchConfig, dispatchMarker, nativeEvent, target, currentTarget, type, eventPhase, bubbles, cancelable, timeStamp, defaultPrevented, isTrusted, view, detail, screenX, screenY, clientX, clientY, ctrlKey, shiftKey, altKey, metaKey, getModifierState, button, buttons, relatedTarget, pageX, pageY, isDefaultPrevented, isPropagationStopped, _dispatchListeners, _dispatchIDs}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of Welcome.

If I change to this.onItemClick.bind(this, item) to (e) => onItemClick(e, item) inside the map function everything works as expected.

If someone could explain what I am doing wrong and explain why do I get this error, would be great

UPDATE 1:
onItemClick function is as follows and removing this.setState results in error disappearing.

onItemClick(e, item) {
    this.setState({
      lang: item,
    });
}

But I cannot remove this line as I need to update state of this component

10
  • 4
    So how this.onItemClick is implemented? Commented Oct 14, 2015 at 5:54
  • @zerkms Thanks for replying, I updated the question, and yes it seems that the problem is in this.setState(), but why does it throw this error? :( Commented Oct 14, 2015 at 6:11
  • 4
    this can also happen if you put async on the function component Commented Jan 10, 2019 at 10:30
  • 1
    As a good practice do not use bind inside the render method. When you use bind inside the render function, what happens is when the render method get invoked a new instance of the onItemClick will be created. So either you can use arrow function syntax or bind your methods in the constructor. You can find more details in the official guide reactjs.org/docs/handling-events.html. Commented Nov 15, 2019 at 18:09
  • 1
    Thanks @PetrosKyriakou. I made my render() method async by mistake. You rock! Commented Dec 17, 2020 at 16:36

54 Answers 54

551

I was having this error and it turned out to be that I was unintentionally including an Object in my JSX code that I had expected to be a string value:

return (
    <BreadcrumbItem href={routeString}>
        {breadcrumbElement}
    </BreadcrumbItem>
)

breadcrumbElement used to be a string but due to a refactor had become an Object. Unfortunately, React's error message didn't do a good job in pointing me to the line where the problem existed. I had to follow my stack trace all the way back up until I recognized the "props" being passed into a component and then I found the offending code.

You'll need to either reference a property of the object that is a string value or convert the Object to a string representation that is desirable. One option might be JSON.stringify if you actually want to see the contents of the Object.

Sign up to request clarification or add additional context in comments.

9 Comments

So, if you do have an object, how would you go about transforming it into something desirable?
You'll need to either reference a property of the object that is a string value or convert the Object to a string representation that is desirable. One option might be JSON.stringify if you actually want to see the contents of the Object.
Encountered same error and this explaination solved my issue. 1 UP for this. :)
Ahh, I had the same issue of the error message pointing at the wrong line - it said the error was in this.setState({items: items}) when really it blew up further down where I was trying to display that variable using {this.state.items}. JSON.stringify fixed it!
For future readers: No don't convert to string. Do this instead: const Lcomponent = this.whateverReturnsObject(); then in render(){ return <Lcomponent /> } Thats its.
|
136

So I got this error when trying to display the createdAt property which is a Date object. If you concatenate .toString() on the end like this, it will do the conversion and eliminate the error. Just posting this as a possible answer in case anyone else ran into the same problem:

{this.props.task.createdAt.toString()}

3 Comments

Bingo! I had this problem but was thrown off track because the table that was displaying it would load (and reload) just fine. React would only throw the objects are not valid invariant violation when I added a row. Turns out I was converting the Date() object to a string before persisting it so only my new rows had objects for the created date. :( Learn from my wayward example people!
a more broad approach is to use ternary statements in your components' selective logic, see my answer to a similar problem I kept encountering here stackoverflow.com/a/59108109/1483143
I definitely had this problem. I was using a React Grid from DevExtreme and it didn't like my date property in my object array. Converting it to a string using .toString() helped right away.
65

I just got the same error but due to a different mistake: I used double braces like:

{{count}}

to insert the value of count instead of the correct:

{count}

which the compiler turned into {{count: count}}, i.e. trying to insert an Object as a React child.

5 Comments

what {{}} are meant for/
@MuneemHabib it's just ES6 syntax. React needs one pair of {}. The inner pair is treat as ES6 code. In ES6, {count} is the same as {count: count}. So when you type {{count}}, that is exactly the same as { {count: count} }.
Had this error -- this was the problem. In assigning my variable to state in the constructor I had this.state = {navMenuItems: {navMenu}}; ... which basically turned my JSX navMenu into a generic object. Changing to this.state = {navMenuItems: navMenu}; got rid of the unintentional 'cast' to Object and fixed the issue.
I guess you came from Angular world :D
bouncing around front end technologies, this was my problem. It's so obvious now! Thanks
34

Just thought I would add to this as I had the same problem today, turns out that it was because I was returning just the function, when I wrapped it in a <div> tag it started working, as below

renderGallery() {
  const gallerySection = galleries.map((gallery, i) => {
    return (
      <div>
        ...
      </div>
    );
  });
  return (
    {gallerySection}
  );
}

The above caused the error. I fixed the problem by changing the return() section to:

return (
  <div>
    {gallerySection}
  </div>
);

...or simply:

return gallerySection

2 Comments

or you can simply use return gallerySection if you want to avoid an extra div
Returning gallerySection instead of <div>{gallerySection}</div> helped me.
31

React child(singular) should be type of primitive data type not object or it could be JSX tag(which is not in our case). Use Proptypes package in development to make sure validation happens.

Just a quick code snippet(JSX) comparision to represent you with idea :

  1. Error : With object being passed into child

    <div>
    {/* item is object with user's name and its other details on it */}
     {items.map((item, index) => {
      return <div key={index}>
    --item object invalid as react child--->>>{item}</div>;
     })}
    </div>
    
  2. Without error : With object's property(which should be primitive, i.e. a string value or integer value) being passed into child.

    <div>
     {/* item is object with user's name and its other details on it */}
      {items.map((item, index) => {
       return <div key={index}>
    --note the name property is primitive--->{item.name}</div>;
      })}
    </div>
    

TLDR; (From the source below) : Make sure all of the items you're rendering in JSX are primitives and not objects when using React. This error usually happens because a function involved in dispatching an event has been given an unexpected object type (i.e passing an object when you should be passing a string) or part of the JSX in your component is not referencing a primitive (i.e. this.props vs this.props.name).

Source - codingbismuth.com

3 Comments

this link no longer works, however I find the structure of your answer to be the most informative in my use case. This error is produceable in both web and react native environments, and often occures as a lifecycle error when attempting to .map() an array of objects within a component using async lifecycle. I came across this thread while using react native react-native-scrollview
Glad, that you find it useful and thanks for flagging link issue.
This helped me. Return a property rather than an object: return <p>{item.whatever}</p>;
21

Mine had to do with forgetting the curly braces around props being sent to a presentational component:

Before:

const TypeAheadInput = (name, options, onChange, value, error) => {

After

const TypeAheadInput = ({name, options, onChange, value, error}) => {

1 Comment

My problem was most similar to yours, so applying your solution helped me. +1 and Thanks!
18

I too was getting this "Objects are not valid as a React child" error and for me the cause was due to calling an asynchronous function in my JSX. See below.

class App extends React.Component {
    showHello = async () => {
        const response = await someAPI.get("/api/endpoint");

        // Even with response ignored in JSX below, this JSX is not immediately returned, 
        // causing "Objects are not valid as a React child" error.
        return (<div>Hello!</div>);
    }

    render() {
        return (
            <div>
                {this.showHello()}
            </div>
        );
    }
}

What I learned is that asynchronous rendering is not supported in React. The React team is working on a solution as documented here.

3 Comments

what you should instead do is to update state as the data comes in, and then render the components using state values
what you should instead do is to update state as the data comes in, and then render the components using state values
This helped in my case
16

Mine had to do with unnecessarily putting curly braces around a variable holding a HTML element inside the return statement of the render() function. This made React treat it as an object rather than an element.

render() {
  let element = (
    <div className="some-class">
      <span>Some text</span>
    </div>
  );

  return (
    {element}
  )
}

Once I removed the curly braces from the element, the error was gone, and the element was rendered correctly.

1 Comment

Thanks! Remove the curly braces from the element works for me too!
8

For anybody using Firebase with Android, this only breaks Android. My iOS emulation ignores it.

And as posted by Apoorv Bankey above.

Anything above Firebase V5.0.3, for Android, atm is a bust. Fix:

npm i --save [email protected]

Confirmed numerous times here https://github.com/firebase/firebase-js-sdk/issues/871

1 Comment

For anybody attempting the solution proposed by KNDheeraj below, **** 1 down vote If in case your using Firebase any of the files within your project. Then just place that import firebase statement at the end!! I know this sounds crazy but try it!! **************** I did try it and this is not a solution for iOS but for Android on Windows only.
8

I also have the same problem but my mistake is so stupid. I was trying to access object directly.

class App extends Component {
    state = {
        name:'xyz',
        age:10
    }
    render() {
        return (
            <div className="App">
                // this is what I am using which gives the error
                <p>I am inside the {state}.</p> 

                //Correct Way is

                <p>I am inside the {this.state.name}.</p> 
            </div>
        );
    }                                                                             

}

1 Comment

wow this helped I don't understand why you why you have to access object individuals
8

Typically this pops up because you don't destructure properly. Take this code for example:

const Button = text => <button>{text}</button>

const SomeForm = () => (
  <Button text="Save" />
)

We're declaring it with the = text => param. But really, React is expecting this to be an all-encompassing props object.

So we should really be doing something like this:

const Button = props => <button>{props.text}</button>

const SomeForm = () => (
  <Button text="Save" />
)

Notice the difference? The props param here could be named anything (props is just the convention that matches the nomenclature), React is just expecting an object with keys and vals.

With object destructuring you can do, and will frequently see, something like this:

const Button = ({ text }) => <button>{text}</button>

const SomeForm = () => (
  <Button text="Save" />
)

...which works.

Chances are, anyone stumbling upon this just accidentally declared their component's props param without destructuring.

1 Comment

This should appear as the correct answer, newbie mistake ;)
6

Just remove the curly braces in the return statement.

Before:

render() {
    var rows = this.props.products.map(product => <tr key={product.id}><td>{product.name}</td><td>{product.price}</td></tr>);
    return {rows}; // unnecessary
}

After:

render() {
    var rows = this.props.products.map(product => <tr key={product.id}><td>{product.name}</td><td>{product.price}</td></tr>);
    return rows; // add this
}

Comments

6

This was my code :

class App extends Component {
  constructor(props){
    super(props)
    this.state = {
      value: null,
      getDatacall : null
    }
    this.getData = this.getData.bind(this)
  }
  getData() {
  //   if (this.state.getDatacall === false) {
    sleep(4000)
    returnData("what is the time").then(value => this.setState({value, getDatacall:true}))
    // }
  }
  componentDidMount() {
    sleep(4000)

    this.getData()
  }
  render() {
    this.getData()
    sleep(4000)
    console.log(this.state.value)
    return (
      <p> { this.state.value } </p>
    )
  }
}

when I ran into the error in question. I had to change it to :

 render() {
    this.getData()
    sleep(4000)
    console.log(this.state.value)
    return (
      <p> { JSON.stringify(this.state.value) } </p>
    )
  }

Comments

5

In my case it was i forgot to return a html element frm the render function and i was returning an object . What i did was i just wrapped the {items} with a html element - a simple div like below

<ul>{items}</ul>

Comments

5

I had the same problem because I didn't put the props in the curly braces.

export default function Hero(children, hero ) {
    return (
        <header className={hero}>
            {children}
        </header>
    );
}

So if your code is similar to the above one then you will get this error. To resolve this just put curly braces around the props.

export default function Hero({ children, hero }) {
    return (
        <header className={hero}>
            {children}
        </header>
    );
}

1 Comment

I did not say it wasn't. I think your answer looks better with the indentation. If you disagree please feel free to roll it back.
5

I got the same error, I changed this

export default withAlert(Alerts)

to this

export default withAlert()(Alerts).

In older versions the former code was ok , but in later versions it throws an error. So use the later code to avoid the errror.

Comments

4

If for some reason you imported firebase. Then try running npm i --save [email protected]. This is because firebase break react-native, so running this will fix it.

Comments

4

Just remove the async keyword in the component.

const Register = () => {

No issues after this.

Comments

3

In my case, I added a async to my child function component and encountered this error. Don't use async with child component.

Comments

3

I got this error any time I was calling async on a renderItem function in my FlatList.

I had to create a new function to set my Firestore collection to my state before calling said state data inside my FlatList.

1 Comment

I got the same caused by an async function called by the navigation
3

My case is quite common when using reduce but it was not shared here so I posted it.

Normally, if your array looks like this:

[{ value: 1}, {value: 2}]

And you want to render the sum of value in this array. JSX code looks like this

<div>{array.reduce((acc, curr) => acc.value + curr.value)}</div>

The problem happens when your array has only one item, eg: [{value: 1}]. (Typically, this happens when your array is the response from server so you can not guarantee numbers of items in that array)

The reduce function returns the element itself when array has only one element, in this case it is {value: 1} (an object), it causes the Invariant Violation: Objects are not valid as a React child error.

Comments

2

You were just using the keys of object, instead of the whole object!

More details can be found here: https://github.com/gildata/RAIO/issues/48

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class SCT extends Component {
    constructor(props, context) {
        super(props, context);
        this.state = {
            data: this.props.data,
            new_data: {}
        };
    }
    componentDidMount() {
        let new_data = this.state.data;
        console.log(`new_data`, new_data);
        this.setState(
            {
                new_data: Object.assign({}, new_data)
            }
        )
    }
    render() {
        return (
            <div>
                this.state.data = {JSON.stringify(this.state.data)}
                <hr/>
                <div style={{color: 'red'}}>
                    {this.state.new_data.name}<br />
                    {this.state.new_data.description}<br />
                    {this.state.new_data.dependtables}<br />
                </div>
            </div>
        );
    }
}

SCT.propTypes = {
    test: PropTypes.string,
    data: PropTypes.object.isRequired
};

export {SCT};
export default SCT;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Comments

2

If using stateless components, follow this kind of format:

const Header = ({pageTitle}) => (
  <h1>{pageTitle}</h1>
);
export {Header};

This seemed to work for me

Comments

2

If you are using Firebase and seeing this error, it's worth to check if you're importing it right. As of version 5.0.4 you have to import it like this:

import firebase from '@firebase/app'
import '@firebase/auth';
import '@firebase/database';
import '@firebase/storage';

Yes, I know. I lost 45 minutes on this, too.

1 Comment

Thank you. It solved my problem with firebase (5.9.2) :)
2

This can happen when you try to render objects as child elements, you can find out the root cause by looking for below scenarios.

  1. Check if you are using any double braces in JSX - <span>{{value}}</span> and change it to <span>{value}</span> (I did this mistake since I just moved from Angular to React).

  2. Check of return statements wrapped around braces like below and remove it.

     render() {
       let element = (
        <span>text</span>
       );
    
       return (
        {element}  // => Remove this extra brace
       )
     }
    
  3. Check any other unintentional way you are using object in the JSX

     let nestedObjected = {
        a : '1',
        b : {
           c: '2'
        }
     };
     {Object.keys(nestedObjected).map((key) => {
        return (
            <div>
               <span>{nestedObjected[key]}</span>  // This will cause issue since it will resolve to an object
            </div>
        );
      })}
    

Comments

1

I just put myself through a really silly version of this error, which I may as well share here for posterity.

I had some JSX like this:

...
{
  ...
  <Foo />
  ...
}
...

I needed to comment this out to debug something. I used the keyboard shortcut in my IDE, which resulted in this:

...
{
  ...
  { /* <Foo /> */ }
  ...
}
...

Which is, of course, invalid -- objects are not valid as react children!

Comments

1

I'd like to add another solution to this list.

Specs:

  • "react": "^16.2.0",
  • "react-dom": "^16.2.0",
  • "react-redux": "^5.0.6",
  • "react-scripts": "^1.0.17",
  • "redux": "^3.7.2"

I encountered the same error:

Uncaught Error: Objects are not valid as a React child (found: object with keys {XXXXX}). If you meant to render a collection of children, use an array instead.

This was my code:

let payload = {
      guess: this.userInput.value
};

this.props.dispatch(checkAnswer(payload));

Solution:

  // let payload = {
  //   guess: this.userInput.value
  // };

this.props.dispatch(checkAnswer(this.userInput.value));

The problem was occurring because the payload was sending the item as an object. When I removed the payload variable and put the userInput value into the dispatch everything started working as expected.

Comments

1

If in case your using Firebase any of the files within your project. Then just place that import firebase statement at the end!!

I know this sounds crazy but try it!!

Comments

1

I have the same issue, in my case, I update the redux state, and new data parameters did not match old parameters, So when I want to access some parameters it through this Error,

Maybe this experience help someone

1 Comment

In my case, (Django) ListSerializer and CreateSerializer return same fields and some of them (it's up to your project) are just read-only fields, So fetch Once and whenever create new data just simply update the redux state
1

My issue was simple when i faced the following error:

objects are not valid as a react child (found object with keys {...}

was just that I was passing an object with keys specified in the error while trying to render the object directly in a component using {object} expecting it to be a string

object: {
    key1: "key1",
    key2: "key2"
}

while rendering on a React Component, I used something like below

render() {
    return this.props.object;
}

but it should have been

render() {
    return this.props.object.key1;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.