Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to debug this error: Uncaught (in promise) Error: Objects are not valid as a React child

The full error in console:

Uncaught (in promise) Error: Objects are not valid as a React child (found: object with keys {id, name, description, css, ephemeral, readonly, topPost})
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 exports.(…)

I don't really know what this error means and it doesn't point me to a line in the code, so I don't know what to do.

I am using api.jsx to fetch data from Imgur (specifically I call it in topic-store.jsx) and then trying to render the data in topic-list.jsx

main.jsx

var React = require('react');
var Header = require('./header');
var TopicList = require('./topic-list');

module.exports = React.createClass({
    render: function () {
        return <div>
          <Header />
          {this.content()}
        </div>
    },
    content: function () {
        if (this.props.children) {
            return this.props.children
        } else {
            return <TopicList/>
        }
    }
});

header.jsx

var React = require('react');
var Router = require('react-router');
var Link = Router.Link; //Router's Link object is a renderable component, that turns into an anchor tag when rendered
//Using Link allows a user to change routes without triggering a full page refresh, the content on the page will change but the browser will not refresh

module.exports = React.createClass({
    render: function () {
        return <nav className="navbar navbar-default header">
          <div className="container-fluid">
            <Link to="/" className="navbar-brand">
              Imgur Browser
            </Link>
            <ul className="nav navbar-nav navbar-right">
              <li><a>Topic #1</a></li>
            </ul>
          </div>
        </nav>
    }
});

topic-list.jsx

var React = require('react');
var TopicStore = require('../stores/topic-store');

module.exports = React.createClass({

    getInitialState: function () {
        return {topics: []}
    },

    componentWillMount: function () {
        TopicStore.getTopics().then(function () {
            //We have successfully fetched topics
            //Topics are available on TopicStore.topics
            this.setState({
                topics: TopicStore.topics
            });
        }.bind(this));
    },

    render: function () {
        return <div className="list-group">
          Topic List
          {this.renderTopics()}
        </div>
    },

    renderTopics: function () {
        return this.state.topics.map(function(topic) {
            return <li>
              {topic}
            </li>
        });
    }
});

topic-store.jsx

var Api = require('../utils/api');
var Reflux = require('reflux');

module.exports = Reflux.createStore({

    getTopics: function() {

        return Api.get('topics/defaults').then(function(json) {

            this.topics = json.data;

        }.bind(this));
    }
});

api.jsx

var Fetch = require('whatwg-fetch');
var rootUrl = 'https://api.imgur.com/3/';
var apiKey = 'e80dc51eb3f6d56';

module.exports = window.api = {
    get: function(url) {
        return fetch(rootUrl + url, {
            headers: {
                'Authorization': 'Client-ID ' + apiKey
            }
        }).then(function (response) {
            return response.json()
        });
    }
};
like image 986
Mjuice Avatar asked Jan 21 '16 08:01

Mjuice


People also ask

How do you fix objects are not valid as a React child?

In order to fix this, replace the {item} with {item.name} in the map function. This no longer attempts to render an object as a React child. Instead, it renders the name property of the object.

How do you pass an array of objects into a child component in React?

To pass an array as a prop to a component in React, wrap the array in curly braces, e.g. <Books arr={['A', 'B', 'C']} /> . The child component can perform custom logic on the array or use the map() method to render the array's elements. Copied!

How do you render collection of children in React?

If you meant to render a collection of children, use an array instead." My code is as follows: import React from 'react'; class Home extends React. Component { constructor(props) { super(props); this.

How do you get the promise value from React?

To use the value of a Promise in React, you can use a useEffect() hook with an empty dependency array to wait for the promise to resolve, and store the result in the value of a useState hook. Here's an example of using this method to get a random cat, using the CatAAS API.


2 Answers

The issue relies on the way you render your topic object in the renderTopics method.

When you're doing something like this:

return <li>{topic}</li>

You're basically trying to do:

return <li>{{ id: 1, name: 'One topic' }}</li>

And React don't know how to render a raw object. To fix your issue, specify which keys of your object you want to render. For example:

renderTopics: function () {
  return this.state.topics.map(function(topic) {
    return (<li>{topic.id} {topic.name}</li>)
  });
}
like image 124
Preview Avatar answered Sep 19 '22 17:09

Preview


You are missing <ul></ul> or <ol></ol> tag in topic-list.jsx

Using <ul></ul> tag in the render call for topics:

render: function () {
    return <div className="list-group">
      Topic List
      <ul>
      {this.renderTopics()}
      </ul>
    </div>
},

Update: Incorporating comments from Aperçu for completeness

You need to get the values from the json blob (does not render Raw content):

For topic being {id:1, name:Topic1}

renderTopics: function () {
    return this.state.topics.map(function(topic) {
        return <li>
          {topic.id}{topic.name}
        </li>
    });
}
like image 33
nitishagar Avatar answered Sep 23 '22 17:09

nitishagar