Olatoyosi Olatoyosi - 3 months ago 9
React JSX Question

Maximum call stack exceeded error in ReactJS. Can someone help explain what's going on? (Snippet on JSFiddle)

I'm new to ReactJS and was trying my hands on a simple project. Basically, the snippet create a list of friends from an array and displays the total number of friends.

For some reason, I realized the incrementFriendsCount function throws a "Maximum call stack exceeded error" when I add a new friend

The code snippet below is also available on JSFiddle.



var HelloUser = React.createClass({
getInitialState: function() {
return {
name: "Toyosi",
friends: ["Susanna", "Jibola", "Worreva"],
friendsCount: 0
}
},
addFriends: function(friend) {
this.setState({
friends: this.state.friends.concat([friend])
});
},
componentWillMount: function() {
this.setState({
friendsCount: this.state.friends.length
});
},
incrementFriendsCount: function() {
this.setState({
friendsCount: this.state.friends.length
});
},
render: function() {
return ( < div >
Villain: {
this.state.name
}, No of friends: {
this.state.friendsCount
} < br / >
< AddingTheFriend addNew = {
this.addFriends
}
incCount = {
this.incrementFriendsCount
}
/>
<ListFriends enemies={this.state.friends} / >
< /div>
);
}
});

var ListFriends = React.createClass({
propTypes: {
enemies: React.PropTypes.array.isRequired
},
render: function() {
var allFriends = this.props.enemies.map(function(friend){
return <li>{friend}</li > ;
});

return ( < div > Her evil friends:
< ul > {
allFriends
} < /ul>
</div >
)
}
});

var AddingTheFriend = React.createClass({
getInitialState: function() {
return {
newFriend: ''
}
},
propTypes: {
addNew: React.PropTypes.func.isRequired
},
updateNewFriend: function(change) {
this.setState({
newFriend: change.target.value
});
},
addTheFriend: function() {
this.props.addNew(this.state.newFriend);
this.setState({
newFriend: ''
})
},
componentWillReceiveProps: function() {
this.props.incCount();
},
render: function() {
return ( < div >
< input type = "text"
value = {
this.state.newFriend
}
onChange = {
this.updateNewFriend
}
/>
<button type="button" onClick={this.addTheFriend}>Add Friend</button >
< /div>
)
}
});
React.render(<HelloUser / > , document.getElementById('app'));

<script src="http://fb.me/react-js-fiddle-integration.js"></script>

<div id="app"></div>





I will appreciate if anyone could throw more light on why this error is thrown.

Answer

You are calling this.props.incCount in componentWillReceiveProps which sets the state of the parent component and the effect will be that AddingTheFriend is rendered again, and this.props.incCount is called again. Hence the stack overflow.

Another advice would be that generally you want to be careful and use setState as little as possible, in as few components as possible. Simply increment the friends count at the same time you concat the new friend to parent component's state.

Here's the codepen --much better than JSFiddle in my opinion.

Comments