Instructor: I've added this first statement in the render method of the App component to demonstrate how the App behaves when there is an unhandled exception in the component tree.
If I drop into the terminal and I do an npm run dev, we'll see when the page finishes loading, we don't see our application. If I open up the dev tools, we'll see in our console that we're getting this error. This is the one we were throwing from the render method of App.
The next console.log statement says, "The above error occurred in the App component. Consider adding an error boundary to your tree to customize error handling behavior." Let's do that.
I'll go back to the code. I'll stop the dev server from running. In my source directory, I'm going to add a new file. I'm going to call this defaultErrorBoundary.js. ErrorBoundary is going to be a React component. I'm going to import React from "react".
Then I'm going to export a class as my default export. I'll call it defaultErrorBoundary. That's going to extend React.Component. I'm going to give this state, which will be an object. That's going to have an isError flag. That initial value is going to be false. We're going to give this a render method.
We'll destructure our state. We'll grab that isError property from this.state. I'm also going to destructure props and grab children off of that. Then we're going to return based on if we're in an error state. If isError, then we're going to return a div. Otherwise, we'll just return children.
Now we need the handle setting this error state in the case where there's an unhandled error lower down on our component tree. We're going to do that above render with a static method, getDerivedStateFromError.
All we're going to do here is this will be called if there's an error and we need to return what our new state looks like. We're going to return isError true.
Now that we have this ErrorBoundary component defined, let's go into our index.js file. In between our React.StrictMode and our App component, we're going to add this defaultErrorBoundary.
I'll just move App up in between there. Of course, we have to import that if we want it to work. I'm going to import defaultErrorBoundary from defaultErrorBoundary. With that in place, I'm going to go into my terminal. I'm going to do an npm run dev.
We'll see when our App loads, this time we get our error message because that exception is still being thrown from our App component. If we look in the dev tools, we'll still see this error, but we're not getting the recommendation to add the error boundary because we've already done that.
We'll leave this running. I'm going to go back to app.js. I'm going to remove this throw statement. This time when our App reloads, everything's working fine.
Now we know if an exception is thrown in our component tree, it'll be caught by that error boundary. We can provide some useful messages in an alternate UI so that users aren't left looking at a blank screen, wondering what happened.