user1883050 user1883050 - 9 months ago 90
React JSX Question

"Cannot update during an existing state transition" error in React

I'm trying to do Step 15 of this ReactJS tutorial: React.js Introduction For People Who Know Just Enough jQuery To Get By

The author recommends the following:

overflowAlert: function() {
if (this.remainingCharacters() < 0) {
return (
<div className="alert alert-warning">
<strong>Oops! Too Long:</strong>
</div>
);
} else {
return "";
}
},

render() {
...

{ this.overflowAlert() }

...
}


I tried doing the following (which looks alright to me)

// initialized "warnText" inside "getInitialState"


overflowAlert: function() {
if (this.remainingCharacters() < 0) {
this.setState({ warnText: "Oops! Too Long:" });
} else {
this.setState({ warnText: "" });
}
},

render() {
...

{ this.overflowAlert() }
<div>{this.state.warnText}</div>

...
}


And I received the following error in the console in Chrome Dev Tools:


Cannot update during an existing state transition (such as within
render
or another component's constructor). Render methods should be
a pure function of props and state; constructor side-effects are an
anti-pattern, but can be moved to
componentWillMount
.


Here's a bin:

http://jsbin.com/divonabawa/1/edit?html,js,output

Why won't my solution work and what does this error mean?

Answer Source

Your solution does work because it doesn't make sense logically. The error you receive may be a bit vague, so let me break it down. The first line states:

Cannot update during an existing state transition (such as within render or another component's constructor).

Whenever a React Component's state is updated, the component is rerendered to the DOM. In this case, there's an error because you are attempting to call overflowAlert inside render, which calls setState. That means you are attempting to update state in render which will in then call render and overflowAlert and update state and call render again, etc. leading to an infinite loop. The error is telling you that you are trying to update state as a consequence of updating state in the first place, leading to a loop. This is why this is not allowed.

Instead, take another approach and remember what you're trying to accomplish. Are you attempting to give a warning to the user when they input text? If that's the case, set overflowAlert as an event handler of an input. That way, state will be updated when an input event happens, and the component will be rerendered.