Errors are a normal part of application development. A component might throw an error or fail to render when it receives unexpected data, a property is missing, or its rendering logic fails. When any of these cases happen, the application may display a blank screen or an unexpected ui instead of the content the user expects.
React offers a feature called Error Boundaries to handle such situations. An error boundary catches all these errors that could occur while rendering React components and displays a fallback ui instead of the affected component crashing. In this blog, we will learn what error boundaries are and how to create one and use it in a React application.
1. What Is an Error Boundary?
An Error Boundary is a React component that detects JavaScript errors in its child components during rendering and lifecycle methods, preventing the entire application from crashing by displaying an alternative UI when an error occurs. Error boundaries are mainly useful for larger applications where different components are used to handle different responsibilities.
2. Create an Error Boundary
React’s built-in error boundary functions usually use class components. So we can create a class-based error boundary. We can also write it as a function also if we want. Create a file named ErrorBoundary.jsx.
import { Component } from "react";
export default class ErrorBoundary extends Component {
state = { hasError: false };
static getDerivedStateFromError() {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return <h2>Something went wrong.</h2>;
}
return this.props.children;
}
}3. Use the Error Boundary in Application
Now, once the error boundary is ready, we can wrap the components that should be protected with the error boundary. For instance, we can create a component that intentionally triggers an error.
function UserProfile() {
throw new Error("Failed to render user profile.");
return <h2>User Profile</h2>;
}Now, we can use the error boundary in App.jsx
import ErrorBoundary from "./ErrorBoundary";
function App() {
return (
<div>
<h1>My Application</h1>
<ErrorBoundary>
<UserProfile />
</ErrorBoundary>
</div>
);
}
export default App;
When the UserProfile component throws an error during rendering, the error boundary displays “Something went wrong” instead of crashing the application.
4. Create a Fallback UI
Now, it displays a basic error message, but a real application needs to provide a more helpful message on error and a retry option. Update the error boundary with this.
import { Component } from "react";
export default class ErrorBoundary extends Component {
state = { hasError: false };
static getDerivedStateFromError() {
return { hasError: true };
}
handleReset = () => {
this.setState({ hasError: false });
};
render() {
if (this.state.hasError) {
return (
<div className="flex flex-col items-center justify-center p-6 text-center">
<h2 className="text-lg font-semibold text-red-700">
Something went wrong.
</h2>
<p className="mt-2 text-sm text-gray-600">
Try loading this section again.
</p>
<button
onClick={this.handleReset}
className="mt-4 rounded-md bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700"
>
Try again
</button>
</div>
);
}
return this.props.children;
}
}5. Log Errors for Debugging
Displaying a fallback message can help users, but for developers, passing more info about errors will be helpful. We can use the componentDidCatch() lifecycle method for logging the errors that are caught by the error boundary. Add this method to the code.
componentDidCatch(error, info) {
console.error("Caught by Error Boundary:", error);
console.error("Component stack:", info.componentStack);
}Error boundaries are an important part of building reliable React applications. They can catch all errors that can occur at runtime in components and display a fallback ui instead of leaving users with a broken interface. You can wrap all components that need the protection of the error boundary and handle the errors efficiently. We can combine the error boundaries with proper api failure handling and asynchronous operation handlers to build a better React application.
To read more about How to Build an API Search with Debouncing in React, refer to our blog, How to Build an API Search with Debouncing in React.