Dani Moss Dani Moss - 3 months ago 23
Javascript Question

Lynda.com React.js Objects are not valid as a React Child

Just started learning React.js and have been using a Lynda.com to get the hang of things. Even though the video series is outdated as mentioned in an earlier post, I've been able to piece together the project with the help of other Stack posts and Google. But this error has me stumped.

I'm at the point of trying to add new notes to a bulletin board app. When I click on the add button (on the top right of the screen) it throws a React Minified #31 error, saying the object I'm using is not valid as a React child. I'm thinking it has to do with the button I just created, but I have no idea how to fix this.

I'm using React version 15.3.1 and Babel version 5.8.29 (as used in the tutorial).

Note.js

var Note = React.createClass({
getInitialState: function() {
return {editing: false}
},
edit: function() {
this.setState({editing: true});
},
save: function() {
// var val = ReactDOM.findDOMNode(this.refs.newText).value;
this.props.onChange(ReactDOM.findDOMNode(this.refs.newText).value,
this.props.index);
this.setState({editing: false});
},
remove: function() {
this.props.onRemove(this.props.index);
},
renderDisplay: function() {
return (
<div className="note">
<p>{this.props.children}</p>
<span>
<button onClick={this.edit}
className="btn btn-primary glyphicon glyphicon-pencil"/>
<button onClick={this.remove}
className="btn btn-danger glyphicon glyphicon-trash"/>
</span>
</div>
);
},
renderForm: function() {
return (
<div className="note">
<textarea ref="newText" defaultValue={this.props.children}
className="form-control"></textarea>
<button onClick={this.save} className="btn btn-success btn-sm glyphicon glyphicon-floppy-disk" />
</div>
)
},
render: function() {
if (this.state.editing) {
return this.renderForm();
}
else {
return this.renderDisplay();
}
}
});

var Board = React.createClass({
propTypes: {
count: function(props, propName) {
if (typeof props[propName] !== "number") {
return new Error ('The count property must be a number');
}
if (props[propName] > 100) {
return new Error ('Creating' + props[propName] + 'is silly');
}
}
},
getInitialState: function() {
return {
notes: []
};
},
add: function(text){
var array = this.state.notes;
array.push(text);
this.setState({notes:array});
},
update: function(newText, i) {
var array = this.state.notes;
array[i] = newText;
this.setState({notes:array});


},
remove: function(i) {
var array = this.state.notes;
array.splice(i, 1);
this.setState({note:array});

},
eachNote: function(note, i) {
return (
<Note key={i}
index={i}
onChange={this.update}
onRemove={this.remove}
>{note}</Note>
);
},
render: function() {
return <div className="board">
{this.state.notes.map(this.eachNote)}
<button className="btn btn-sm glyphicon glyphicon-plus"
onClick={this.add}></button>
</div>
}

});

ReactDOM.render(<Board count={10}/>,
document.getElementById('react-container'));

Answer

The problem is actually in your Board class. You're passing this.add as an event handler to the button's onClick property. Keep in mind that event handlers are always passed an event as the first parameter, which means that in your this.add function, you're adding an Event object to your notes state, not a string, like the current signature implies. Then, when the eachNote function is executing, it's trying to render that Event as a child of your Note component, which is what is causing this error.

If you're trying to add a new note, chances are you won't want it to have any text in it at all. So I think you could safely ignore the event that is being passed to this.add.

add: function() {
    var array = this.state.notes;
    array.push('');
    this.setState({notes:array});
},
Comments