Skip to content

Error during setState callback unmount the entire app #14522

@alonfixler

Description

@alonfixler

I'm using React 16.7 and I've noticed that if an unexpected error happens during a setState callback in one of my inner component the entire app is unmounted.
I tried wrapping the inner component and also my app's main component with an ErrorBoundary component. The error itself was caught in both the boundaries (where I just tried to re-render the UI) but that didn't prevent from my app to break.
The weird thing is that the setState callback is trigged inside of an event handler which is called after the page finished rendering.
If I move the faulty code from the callback and place it right after setState is called everything works as expected and nothing breaks.

I've read #11409 and I would expect that since it happens in the callback of setState it would be treated as any other error happening not as part of a lifecycle method. Also, if it's part of a lifecycle method then I would expect my ErrorBoundary to catch without the app being unmounted.

My code looks something like this:

 const MainComponent = () => (
    <ErrorBoundary>
      <InnerComponent/>
    </ErrorBoundary>          
  );

 class InnerComponent extends React.Component {

    constructor() {
        super();

        this.state = {
            dummyState: false
        };

        this.onClick = this.onClick.bind(this);
    }

    onClick() {
        this.setState({
            dummyState: true
        }, (args) => args.key1.key2);
    }

    render() {
        return (
            <ErrorBoundary>
                 <button onClick={this.onClick}>Error button</button>
            </ErrorBoundary>
        );
    }
}

class ErrorBoundary extends Component {

    static getDerivedStateFromError() {
        return { hasError: true };
    }

    constructor(props) {
        super(props);
        this.state = { hasError: false};
    }

    componentDidCatch(error) {
        console.log('report error');
    }

    render() {
        if (this.state.hasError) {
            // do nothing
        }

        return this.props.children;
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions