15

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

3 Answers 3

24

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>)
  });
}
Sign up to request clarification or add additional context in comments.

Comments

2

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

4 Comments

I made this change but I'm still getting the same error.
@Mjuice Can you try changing the if..else here: if (this.props.children) { return this.props.children } else { return <TopicList/> } to just use the <TopicList/> and see if that works
Nice edit. Mind citing my answer instead of editing without attribution?
Srry for that @Aperçu - Added :) Just for documentation - I did go ahead and try the whole thing and then posted that - did use the same language though
0

to complete previous answers, add brackets arround your JSX returned in render functions

exemple 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/>
        }
    }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.