While building applications, errors are inevitable. They might come from APIs, UI or from several other places.
It's very important to handle these errors gracefully & maintain good UX despite these errors.
Error Boundary is one such way of error handling in React.
To understand this, let's understand the situation before the introduction of the Error Boundary.
Before Error Boundaries, the errors occurring inside components eventually propagated & broke the UI or rendered the white screen.
This caused a really bad UX.
Error Boundary helps us to handle such errors & display a fallback UI instead of breaking the UI or white screen displayed.
React v16 officially introduced Error Boundary.
It's a Class-Based Component which can be used to wrap your application.
It accepts a fallback UI to be displayed in case your application has errors or otherwise, it simply renders the children component to resume the normal flow of your application.
This is how the React Documentation recommends using it,
class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { // Update state so the next render will show the fallback UI. return { hasError: true }; } componentDidCatch(error, info) { // Example "componentStack": // in ComponentThatThrows (created by App) // in ErrorBoundary (created by App) // in div (created by App) // in App logErrorToMyService(error, info.componentStack); } render() { if (this.state.hasError) { // You can render any custom fallback UI return this.props.fallback; } return this.props.children; } }
It cannot catch errors occurring in,
There's a npm package called react-error-boundary which is a wrapper on top of the traditional Error Boundary component.
Using this package, we're able to overcome all the issues faced in the traditional Error Boundary component.
You can wrap your entire application with or you can wrap individual components with .
The granularity of implementation is up to you.
Let's understand how to use it.
import React from 'react'; import { ErrorBoundary } from "react-error-boundary"; const App = () => { return <ErrorBoundary fallback={<div>Something went wrong</div>}> /* rest of your component */ </ErrorBoundary> }
This is the simplest example of using ErrorBoundary. There's more to this library.
Let's try to understand API with different scenarios.
1. I want to show a generic fallback UI for Errors in the Application
import React from 'react'; import { ErrorBoundary } from "react-error-boundary"; const App = () => { return <ErrorBoundary fallback={<div>Something went wrong</div>}> /* rest of your component */ </ErrorBoundary> }
2. I want to show specific error details in my fallback component
import React from 'react'; import { ErrorBoundary } from "react-error-boundary"; function fallbackRender({ error, resetErrorBoundary }) { // Call resetErrorBoundary() to reset the error boundary and retry the render. return ( <div role="alert"> <p>Something went wrong:</p> <pre style={{ color: "red" }}>{error.message}
Instead of fallback or fallbackRender, you can also use a React Component.
import React from 'react'; import { ErrorBoundary } from "react-error-boundary"; const Fallback = ({ error, resetErrorBoundary }) => { // Call resetErrorBoundary() to reset the error boundary and retry the render. return ( <div role="alert"> <p>Something went wrong:</p> <pre style={{ color: "red" }}>{error.message}
3. I want to Log my errors
import React from 'react'; import { ErrorBoundary } from "react-error-boundary"; const logError = (error: Error, info: { componentStack: string }) => { // Do something with the error, e.g. log to an external API }; const Fallback = ({ error, resetErrorBoundary }) => { // Call resetErrorBoundary() to reset the error boundary and retry the render. return ( <div role="alert"> <p>Something went wrong:</p> <pre style={{ color: "red" }}>{error.message}
4. I want to catch errors in event handlers & async code
import { useErrorBoundary } from "react-error-boundary"; function Example() { const { showBoundary } = useErrorBoundary(); const getGreeting = async(name) => { try { const response = await fetchGreeting(name); // rest of your code } catch(error){ // Show error boundary showBoundary(error); } } useEffect(() => { getGreeting() }); return <Whatever UI you want to render/> }
ErrorBoundary is a client component. You can only pass props to it that are serializeable or use it in files that have a "use client"; directive.
1. What is a serializable prop?
Serilzable prop means it can be converted to byte stream in such a way that byte stream can be converted back to orignal prop.
A common way to do that in Javascript is JSON.stringify() & JSON.parse().
2. How to use "use client"; directive?
Simply mention it at top of the file
"use client";
There are a few more variations you can use. But this article is good enough to get you started.
Checkout their full documentation here.
Please let me know in the comments if you found it helpful.
Happy Coding!
The above is the detailed content of Mastering Error Boundaries in React: A Guide to Effective Error Handling. For more information, please follow other related articles on the PHP Chinese website!