3

I use React 16 with Error Boundary functionality: Profile.js

class Profile extends Component {
constructor(props) {
    super(props);
    this.state = {
        // user: {
        //     name: "Ha (Huck) H.K. NGUYEN"
        // }
        user: null
    };
    this.updateUser = this.updateUser.bind(this);
}

updateUser() {
    this.setState({ user: null })
}

render() {
    const { user } = this.state;
    console.log(user);
    return <div className="App">
            {user.name}
            <button onClick={this.updateUser}>
                Update
            </button>
        </div>
}
}

ErrorBoundary.js

class ErrorBoundary extends Component {
constructor(props) {
    super(props);
    this.state = {
        hasError: false
    }
}
componentDidCatch(error, errorInfo) {
    this.setState({ hasError: true });
}
render() {
    const { children } = this.props;
    const { hasError } = this.state;
    if (hasError) {
        return <HasError />
    }
    return children
}
}

App.js

class App extends Component {
render() {
    return <div className="App">
    <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <h1 className="App-title">Welcome to React</h1>
    </header>
    <ErrorBoundary>
        <Profile />
    </ErrorBoundary>
</div>
}
}

I saw the functional component is still called after the error happened and has been caught. Can anyone please explain why the render function is called. enter image description here

For someone doesn't know, follow the answer from link, you can see the error boundary by press the key esc.

Einsamer
  • 1,069
  • 4
  • 17
  • 34

3 Answers3

2

As you already mentioned in your question that pressing Esc cancels the overlay and you can see the ErrorBoundary message and the visibility of the overlay is limited to development environment.

You can check more about it here

However as to why the render function is executing, you need to know that once the render function is executed and there is a RuntimeError that is being thrown by your code, is the only time that componentDidCatch method of your ErrorBoundary. Also create-react-app has a functionality whereby it listens to the RuntimeErrors that are being produced and it reports the root cause of the Error which is what you see in the overlay.

To check the relevant code that produces the Overlay, you can check this github code

I hope I am able to answer your question.

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
1

https://codesandbox.io/s/nn9kw2k3ql

Here is a working example, you will need to press esc.

I put in your Profile without changing anything, and it worked as expected as well.

Just to be clear...

The red-ish overlay that you can click esc on, will be removed once you are in production setting. They are for development use only. That's why you want to implement errorBoundary which will work in both cases.

So if there is some error in your code during development, both errors will show up.

And if you look at the console, you get these messages:

false // from ErrorBoundary this.state.error
i am here  // inside the potential error componenet
i am here  // inside the potential error componenet
The above error occurred in the <Profile> component: //from Error Boundary
true // from ErrorBoundary this.state. error

First false is coming from ErrorBoundary, because on initial load, there is no error, so it will try to render the children, then it logs i am here in the children. And found error, and update the errorboundary component. After that, you do not see I am here again, because errorboundary kicked in and no longer rendering the children

In order for errorBoundary to know there is some error in its children, error has to occur first. Otherwise it does not know. JS is a dynamically typed lang, everything needs to happen during run time.

leogoesger
  • 3,476
  • 5
  • 33
  • 71
  • Yes, I know, but the `console.log(user)` in `Profile` still run, I don't know why. :D You can check at line 21 in the sandbox, `ErroComp`. :D – Einsamer Jul 23 '18 at 03:23
  • @Einsamer I think there are mis-understading on how error boundary works in comparsion to errorhandling in create-react-app. In production, those error overlay will be disabled. Only the Error message be displayed. – leogoesger Jul 23 '18 at 03:29
  • @Einsamer I added a bit more description to clear things up a bit. Basically in order for `errorBoundary` to know there is an error which triggers re-render, an error has to occur first since everything happens in run-time in JS – leogoesger Jul 23 '18 at 03:37
1

I think you have a wrong condition as follows:

if (!hasError) {
        return <HasError />
    }

Here you want to show error if hasError is true, right? otherwise will render Profile component.

And also componentDidCatch is built in react16 so if render function throws any error this method will be triggered automatically.

Shahriat Hossain
  • 340
  • 4
  • 12