Angular 10 Tutorials

Solve – Objects are not valid as a React child error

objects are not valid as a react child

Let solve the React.js “uncaught error: objects are not valid as a React child (found object with keys_u_v_w_w) if you meant to render a collection of children, use an array instead.” The first approach to any problem is to identify the root cause, so let me show you the reason why this error occurs and then we will proceed with the solution. When you have a list of items in an array or object and you try to render it directly in JSX code, react will throw this error as a result of not knowing which object property or array index to render.

A quick way to fix or solve this error is to loop through the object properties or the array items with the ‘map()’ function or a foreach loop. The image below shows how react present the bug with a hint.

objects are not valid as a react child

Here is a source-code of the reason behind the occurrence of react the error.

export default function App() {
  const students = [
    {id: 1, name: 'Justice', country: 'France'},
    {id: 2, name: 'David', country: 'England'},
    {id: 3, name: 'James', country: 'Brazil'},
  ];

  const obj = {
    id: 4,
    name: ‘Linda',
    country: 'Denmark',
  };

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

  return (
    <div>
<!—This will cause an error-->
      {students}

      {obj}
    </div>
  );
}

You can see from the above code that directly trying to render the array and the object in the Dom cause an issue in the JSX code. Instead of looping through each object property in the array, we have rather rendered the memory address of the array. The quick solution is to use the ‘map()’ method to first loop through each object in the array and then proceed to access each object property. Remember, the ‘map()’ method has parameters to get this done.

export default function App() {
  const students = [
    {id: 1, name: 'Justice', country: 'France'},
    {id: 2, name: 'David', country: 'England'},
    {id: 3, name: 'James', country: 'Brazil'},
  ];	

  const obj = {
    id: 4,
    name: ‘Linda',
    country: 'Denmark',
  };

  return (
    <div>
      { students.map((student, index) => {
        return (
          <div key={index}>
            <h2>name: { student.name}</h2>
            <h2>country: {student.country}</h2>

            <hr />
          </div>
        );
      })}

      <hr />
      <hr />
      <hr />

      <div>
        <h2>name: {obj.name}</h2>
        <h2>county: {obj.country}</h2>
      </div>

      <hr />
    </div>
  );

}

From the above code, we have provided 2 argument to the ‘map()’ method which represent, each student object and index in the array respectively. Because we have access to each student object, we are able to access each object property using the ‘student’ variable. The react error – objects are not valid as a react child is solved because we are now rending a primitive strings and numbers value instead of an array or object in the JSX code. That’s a quick JSX concept you need to be aware of all the time “render only primitive values like numbers, string and float.”

Check also, reactscript command not found.

A good coding practice is to debug your code at some point to check if some variables are of the expected type. When it comes to debugging a react app, we mostly use the ‘console.log()’ and ‘JSON.stringify()’  to convert the object passed into it as a string before rendering.

export default function App() {
  const students = [
    {id: 1, name: 'Justice', country: 'France'},
    {id: 2, name: 'David', country: 'England'},
    {id: 3, name: 'James', country: 'Brazil'},
  ];

  const obj = {
    id: 4,
    name: ‘Linda',
    country: 'Denmark',
  };

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

  return (
    <div>
      <h4>{JSON.stringify(students)}</h4>

      <h4>{JSON.stringify(obj)}</h4>
    </div>
  );

}

If your react application make use of the Date object, you need to note that its also an object of other properties and methods. Therefore, rendering the ‘Date’ object directly in your JSX code will cause the “Objects are not valid as a React child” error.

export default function App() {
  var date = new Date();

  // Objects are not valid as a React child (found: [object Date]).
 // because new Date() is not a primitive type
  return (
    <div>
      <h4>{ date}</h4>
    </div>
  );
}

The solution to the above issue is for you to access any method or property on the ‘Date’ object, e.g. ‘toLocalDateString()’.

export default function App() {
  return (
    <div>
    <!—you’re accessing a method that returns a value of primitive type, so there won’t be no error-->
      <h2>{date.toLocaleDateString()}</h2>
    </div>
  );
}

The error may still persist if you render a variable with double curly-braces.

export default function App() {
  var greetings = 'hello, good morning?';

  // Objects are not valid as a React child (found: object with keys {message}).
  return (
    <div>
      <h4>{{greetings}}</h4>
    </div>
  );
}

React now assumes that we’re trying to render an object because the ‘greetings’ variable is wrapped inside double curly braces. Remember to wrap all your variables or properties in a single curly brace.

export default function App() {
  var greetings = 'hello, good morning?';

  // The error is gone because JSX sees the variable as an expression and not an object. 
  return (
    <div>
      <h4>{greetings}</h4>
    </div>
  );
}

If the error still exists, then it likely that you are calling an async function in your JSX code. Normal functions work on the main thread in synchronous order and returns a value immediately after its execution. However, async function returns a promise because its asynchronous and will throw the objects not valid error when called in JSX code.

export default function App() {
  async function getStudents() {
    return Promise.resolve(42);
  }

  // Objects are not valid as a React child (found: [object Promise]).
  return (
    <div>
      <h4>{ getStudents()}</h4>
    </div>
  );
}

A work around this error to execute the ‘async’ function inside an event handler lick ‘onload’ and ‘onclick’ calling the function in a ‘useEffect’ hook will also work. With this you will be rendering a primitive value like a number instead of promise object example…

import {useEffect, useState} from 'react';

export default function App() {
  const [num, setNum] = useState(0);

  useEffect(() => {
    async function getStudents() {
      const result = await Promise.resolve(42);

      setNum(result);
    }

    getStudents();	
  }, []);

  return (
    <div>	
      <h4>{num}</h4>
    </div>
  );
}

Another reason why this error may occur is when you surround an object that needs to be returned in curly-braces. You may find yourself doing this often if you’re prone to object destructuring.

render() {
    var student_rows = this.props.student.map(student => <tr key={ student.id}><td>{student.name}</td><td>{student.age}</td></tr>);
    return {student_rows}; // This will cause an unnecessary error
}

Simply remove the curly braces wrapped around the return object and the error will be fix.

render() {
    var student_rows = this.props.student.map(student => <tr key={ student.id}><td>{student.name}</td><td>{student.age}</td></tr>);
    return student_rows;
}

What Causes objects are not valid as a react child Error?

  1. An array of items is not iterated with the map() method or for-loop function.
  2. Returning a whole object instead of one of its properties.
  3. Accessing an object property that does not exist.
  4. A function returns an object instead of primitive value.
  5. Calling a function that returns a promise.

Check also, fix error: foreach is not a function

Summary Of React Object Not Valid Error

React.JS does not provide a clean way to render different types of objects. So, it’s the job of every ReactJS developer to apply his or her JavaScript/Typescript knowledge together with JSX to render a collection correctly.  The hack is to make sure the object you are rendering will output a primitive value. However, Boolean is also a primitive but it will not render true/false value. Also, the error is always Cleary stated that ReactJS cannot directly render objects as children, and that’s when you render a collection incorrectly. My only hack for you is to read stack trace of every bug you will come across. Doing that will help you to identify the root cause of every error and by knowing why the issue persist, you will be able to solve it easily.

Let me know your thought, also if you encounter any challenges whiles applying any of the above tips, let me know in the comment section below.

Thanks for reading.

Tagged

About Justice Ankomah

computer science certified technical instructor. Who is interested in sharing (Expert Advice Only)
View all posts by Justice Ankomah →

Leave a Reply

Your email address will not be published. Required fields are marked *