here is an app https://gist.github.com/gre/52e28f74eda0beccc17e880efe18c250
There is intentionally a bug in this app: the App component returns `<Demo setVariables={v=>this.setState(..)} variables={..} />` and `Demo` calls `setVariables` in componentDidMount and componentWillReceiveProps (it shouldn't, this is bad user code). What this issue raises is a regression behaviour in React 16 compared to 15.


in React 15 : it renders but you directly get a `Uncaught RangeError: Maximum call stack size exceeded`.
in React 16 : nothing renders, the app never loads and the browser is spinning forever! I think React is stuck in an infinite recursion.

I presume this is because fiber is by nature async. The fact things never ends makes it very hard to investigate and isolate the source of the problem in a large codebase.
should there be some sort of maximum call stack in Fiber ?

> Context: When we migrated our app to latest React Native recently, we had a weird freezing case: the app was completely unresponsive (no button works) but you could still do native actions like scroll a ScrollView. however, even the RN devtool menu action was not working (like the inspector) – probably because it involves JS and React was just stuck in this recursion loop.
In our case, the issue was because calling `relay.setVariables` in lifecycle but with a wrong logic. for some reason our code used to work in the past but now creates this recursion loop.
'Invalid argument passed as callback. Expected a function. Instead ' +
        'received: [object Object]',
    );
    expectDev(console.error.calls.argsFor(2)[0]).toContain(
      'forceUpdate(...): Expected the last optional `callback` argument to be ' +
        'a function. Instead received: [object Object].',
    );
    expect(console.error.calls.count()).toBe(3);
  });
  it('does not update one component twice in a batch (#2410)', () => {
    class Parent extends React.Component {
      getChild = () => {
        return this.refs.child;
      };
      render() {
        return <Child ref="child" />;
      }
    }
    var renderCount = 0;
    var postRenderCount = 0;
    var once = false;
    class Child extends React.Component {
      state = {updated: false};
      componentWillUpdate() {
        if (!once) {
          once = true;
          this.setState({updated: true});
        }
      }
      componentDidMount() {