Invariant Violation: Objects Are Not Valid as a React Child

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

48 Answers

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.

9

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

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 presumably turned into {{count: count}}, i.e. trying to insert an Object as a React child.

5

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

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

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

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

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

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 firebase@5.0.3

Confirmed numerous times here

1

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

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

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
}

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

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.

0

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>
    )
  }
}

and I was running into this error. I had to change it to

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

Hope this helps someone!

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

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>
Chloe Bennett

Chloe Bennett

Culture, Media & Entertainment Columnist

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.