React, Uncaught RangeError: Maximum call stack size exceeded

The problem is you are calling setState from inside your render function. State changes should only happen as a result of something changing: user clicked on a button, the browser window was resized, a picture was taken, etc.

Never ever ever ever update the state while rendering (repeat that last sentence 20 times and never forget it).

Here is the problem code:

render () {
    ...
    this.setState({
      iconStyle: _props.iconStyle
    });

    this.setState({
      style: _props.style
    });
    ...
}

The above code would cause an infinite loop of sorts because setState causes render to be called. Since iconStyle and style are props, and props cannot change, you should use those props to build your initial state.

getInitialState() {
  return {
      iconStyle: this.props.iconStyle,
      style: this.props.style,
      cursorPos: {},
  };
}

Later, if someone clicks a button and you want the iconStyle to change, you would create a click handler which updates your state:

handleClick () {
  this.setState({
    iconStyle: 'clicked'
  });
}

This would cause your component to be rerendered and the new state would be reflected.

Think of your "state" as someone cooking and we are going to take photographs of them cooking. The initial state is "eggs cracked: no, flour poured: no, veggies chopped: no", and you take a picture of this state. Then the chef does something - cracks the eggs. The state has now changed, and you take a picture of it. Then she cuts the veggies. Again, the state has changed and you take a picture.

Each photograph in the analogy represents your "render" function - a snapshot of the "state" at a particular point in time. If every time you took a photograph the flour got poured, well we would have to take another picture because the flour was just poured. Taking another picture would cause more flour to get poured so we'd have to take another picture. Eventually you'd fill the kitchen to the ceiling with a celiac's nightmare and suffocate everybody in the room. You'd also run out of film or hard disk space on your camera.


Thanks to @RyanWheale I noticed my mistake.

In my render function I was returning a button element which called a function which changed a certain state. The returned button looked like this:

<button onclick={this.edit()} className="button-primary">Edit</button>

And my edit function changes some state and looks like this:

edit: function () {
    this.setState({editing: true});
}

So, I my mistake is that I, accidentally, typed the parenthesis after this.edit. So, when the button element was being rendered, the edit function was actually called and chaos happened. Now, when I wrote

<button onclick={this.edit} className="button-primary">Edit</button>

instead of

<button onclick={this.edit()} className="button-primary">Edit</button>

it worked flawlessly. I hope I help someone save hours of his precious life.

Cheers :)