Resolving Error: “Objects are not valid as a React child”

Nearly every developer working in React runs across the error “Objects are not valid as a React child” at some point.

If you are seeing it for the first time, don’t panic! This post will help explain what the error means and how to track down the problem.

Why You’re Seeing the Error

As the error message states, React cannot render objects as children directly. If you are seeing this error, there is a good chance you are trying to render a JS object or collection incorrectly. Here is an example of some invalid children.

import * as React from "react";
export const ExampleComponent: React.FC = () => {
  return (
    <div>
      🛑 Invalid
      <div>{{ foo: 'bar' }} </div>
      <div>{new Date()} </div>
      <div>{['array']} </div>
    </div>
  )
}

React does not try to make any assumptions about how to render objects or a collection. Instead, it is the developer’s job to be more explicit about how they should be rendered.

Debugging the Problem

The “Objects are not valid as a React child” error might mean that a few different things are going wrong.

⚠️ Potential issues: ⚠️
1. Rendering an object (e.g. a JavaScript Date) directly
2. Rendering a collection of items without using a .map()
3. Calling a function that returns an object or other invalid child

This component illustrates the common cases that cause this error as well as examples of valid React children.

import React from "react";
export const Component: React.FC = () => {
  const validChildrenToRender = {
    string: 'string',
    number: 12,
    element: <div>an element!</div>,
    funcThatReturnsValidChild: () => <div>a component!</div>,
  }

  const invalidChildrenToRenderDirectly = {
    object: { something: 'string' },
    array: [{ item: 'item' }],
    date: new Date(),
    funcThatReturnsNonPrimative: () => ({ foo: 'bar' }),
  }
  return (
    <div style={{ width: '100%' }}>
      ✅ Valid
      <div>{validChildrenToRender.string}</div>
      <div>{validChildrenToRender.number}</div>
      <div>{validChildrenToRender.element}</div>
      <div>{validChildrenToRender.funcThatReturnsValidChild()}</div>

      🛑 Invalid
      <div>{invalidChildrenToRenderDirectly.object}</div>
      <div>{invalidChildrenToRenderDirectly.array}</div>
      <div>{invalidChildrenToRenderDirectly.date}</div>
      <div>{invalidChildrenToRenderDirectly.funcThatReturnsNonPrimative()}</div>
    </div>
  )
}

Resolving the Problem

Rendering Objects 📖

React doesn’t know what to do with an object, so you have to tell it exactly how you want it rendered. In this example, there is an object with some details about a book. Instead of rendering book directly, we specify that it should be rendered as the title followed by the author, e.g. “Where the Crawdads Sing by Delia Owens.”

import React from "react";
export const ValidComponent: React.FC = () => {
  const book: Book = { title: "Where the Crawdads Sing", author: "Delia Owens" }
  return (
    <div>
      ✅ Valid
      <div>{book.title} by {book.author}</div>
    </div>
  )
}

Similarly, we call a function that returns some information about the sales of a given book. We can render the output of that function just like we would any other object.

import React from "react";
export const ValidComponent: React.FC = () => {
  const book: Book = { title: "Where the Crawdads Sing", author: "Delia Owens" }
  const getCurrentSalesForBook = (book: Book) => {
    return { 
      salesForCurrentYear: getSalesForCurrentYear(book),
      totalSales: getTotalSales(book)
    }
  )
  return (
    <div>
      ✅ Valid
      <div>{book.title} by {book.author}</div>
      <div>
        This year's sales: ${getCurrentSalesForBook().salesForCurrentYear}
      </div>
    </div>
  )
}

Rendering a Collection of Items 📚

To render a collection, iterate over each item using the .map() method and return a valid React child.

import * as React from "react";
export const ValidComponent: React.FC = () => {
  const array = ["item1", "item2", "item3"]
  return (
    <div>
      ✅ Valid
      <div>
        {array.map((item, i) => (
          <div key={i}>{item}</div>
        ))}
      </div>
    </div>
  )
}

It doesn’t matter what is in your array as long as what you return is a primitive or any valid React child. For example, if you want to render an array of objects, make sure you are explicit about how you want React to render the items. Here is an example to help visualize what this means.

import * as React from "react";
export const ValidComponent: React.FC = () => {
  const groceryList = [
    { name: "Bunch of Kale", quantityNeeded: 1 },
    { name: "Olive oil", quantityNeeded: 1 }
  ];
  return (
    <div>
      ✅ Valid
      <div>
        {groceryList.map((item, i) => (
          <div key={i}>{item.quantityNeeded} {item.name}{</div>
        ))}
      </div>
    </div>
  )
}

In this case, we are telling React to render the grocery list in the format: “1 Bunch of Kale”.

Note: Be sure to add a unique key to each element of an array to help React know which elements have been changed, added or removed. Read more here

Rendering Dates 📆

The simplest approach to resolving invalid rendering of a Date is to use the built in JS .toString() method for Dates. This will convert the Date to a string, which is a primitive, and React will render it without complaint.

import * as React from "react";
export const ValidComponent: React.FC = () => {
  return (
    <div>
      ✅ Valid
      <div>{(new Date).toString()}</div>
    </div>
  )
}

You’ll likely want to have better formatting for Dates than simply converting it to a string. There are various JS date libraries that can help you with this. Check out date-fns and Moment.js as a good starting point.

“Objects are not valid as a React child” – Error Resolved

Remember that React throws an “Objects are not valid as a React child” error instead of making assumptions about how to render objects. The next time you see this error, make sure you are only rendering primitives. Read the stack trace carefully to get a sense of where the issue is coming from in your code. Happy React coding!

Conversation
  • Brunet says:

    Thanks for this article !

  • Royi says:

    ” make sure you are only rendering primitives”

    That’s not true.
    if you try to display boolean , it will not show you “true” although bool is a primitive.

  • Edgar Benzor says:

    Thanks a lot for your article,

    I already know how to fix this error!!

    greetings from Mexico.

  • Brian says:

    Thanks a lot for the information. It is really useful.

  • Comments are closed.