React: Infinite Loop when maximum update depth exceeds

Created on 6 Oct 2017  路  13Comments  路  Source: facebook/react

Do you want to request a feature or report a bug?
Bug
What is the current behavior?
I wrote this component to recreate the warnings from #11081 and to fix it:

class App extends Component {
  constructor() {
    super();
    this.state = {
      value: null,
    };
  }

  render() {
    this.setState({
      value: 'test',
    });

    return <div />;
  }
}

And in the process found that this error came up:

'Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly
calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of
nested updates to prevent infinite loops.'

But the execution did not stop. It was going in an infinite loop and printing 2 variants of the same error one after another.

Screenshot for your reference:
react-bug

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template for React 16: https://jsfiddle.net/Luktwrdm/, template for React 15: https://jsfiddle.net/hmbg7e9w/).
Snippet given above

What is the expected behavior?
There shouldn't be an infinite loop. The execution should stop after printing the error.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
React 16, Chrome 59, Ubuntu. I tested it in older versions of react and this problem is not present there.

Core Utilities Needs Investigation

All 13 comments

Hey, @anushreesubramani! Thanks for the report. I ran the snippet you provided and it seems like it's stopping after the maximum update depth error: https://jsfiddle.net/xonsuqwz/

Can you verify if that JSFiddle is working as expected for you? If so, how does it differ from the code you're running to get the infinite loop?

JSFiddle might work differently. It's worth checking locally.

@gaearon I tested locally with the HTML file below and saw the same results in Chrome for both the production and development builds

<!DOCTYPE html>
<html lang="en">
<head>
  <title></title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <div id="container"></div>
  <script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
  <script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
  <script>
    class App extends React.Component {
      constructor() {
        super();
        this.state = {
          value: null,
        };
      }

      render() {
        this.setState({
          value: 'test',
        });

        return React.createElement('div', null);
      }
    }

    ReactDOM.render(
      React.createElement(App, null),
      document.getElementById('container')
    ); 
  </script>
</body>
</html>

This could also be specific to CRA environment.

@aweary @gaearon The fiddle works fine for me as well. I also tested the html and its fine as well. But its happening in the CRA generated app. So, I guess Dan's guess is right. It could be specific to CRA. Should I open an issue in CRA instead?

Yes please. Although let's keep this one open too for posterity.

i have opened an issue in CRA for the same. https://github.com/facebookincubator/create-react-app/issues/3251

Was fixed inside CRA.

I am still getting this error.

I am still getting the error with React 16.2.0. setState does not called in "componentWillUpdate" or "componentDidUpdate". nestedUpdateCount incremented to 1001.
Error since NESTED_UPDATE_LIMIT set to 1000 and nestedUpdateCount never reset to 0 after the error throws.
_I am not using CRA._

Hey folks鈥攋ust to chime in, I'm still experiencing this in React 16.2 in production. It seems that in the JSFiddle above, the App component is unmounted once the invariant violation occurs. In my app, the component is not unmounted, and anything that calls setState on any component in the UI (for example, an event handler or timer) triggers another "Maximum call depth" error.

I've verified this by creating a component like the JSFiddle one that triggers a "Maximum call depth" exception exactly once and then stops. Any subsequent setState triggers another one.

I can certainly unmount / remount the React root (or maybe I need an error boundary and don't have one), but I think it'd be super great if the error description identified this could happen. I spent a long time looking at those downstream setState calls triggering a "Maximum call depth" error and trying to figure out how on earth they were looping 1000+ times :-)

If you think there's a React bug here please file a new issue with a reproducing example. Thanks.

@gaearon thanks鈥擨 created a Fiddle to file an issue (https://jsfiddle.net/ts8zbh4u/) but it looks like the problem I was encountering has been fixed already in React 16.6. 馃帀

In 16.2, the "Maximum call depth" error triggered via a setState loop in componentDidUpdate in the Fiddle does not reach the parent componentDidCatch, but in 16.6 it does. Will just upgrade my project! 馃檹

Was this page helpful?
0 / 5 - 0 ratings