React v16 introduced the concept of βerror boundariesβ.
This component provides a simple and reusable wrapper that you can use to wrap around your components. Any rendering errors in your components hierarchy can then be gracefully handled.
This module is distributed via npm which is bundled with node and should be installed as one of your project's dependencies:
npm install --save react-error-boundary The simplest way to use <ErrorBoundary> is to wrap it around any component that may throw an error. This will handle errors thrown by that component and its descendants too.
import ErrorBoundary from 'react-error-boundary' function ErrorFallback({error, componentStack}) { return ( <div role="alert"> <p>Something went wrong:</p> <pre>{error.message}</pre> <pre>{componentStack}</pre> </div> ) } const ui = ( <ErrorBoundary FallbackComponent={ErrorFallback}> <ComponentThatMayError /> </ErrorBoundary>, )You can react to errors (e.g. for logging) by providing an onError callback:
import ErrorBoundary from 'react-error-boundary' const myErrorHandler = (error: Error, componentStack: string) => { // Do something with the error // E.g. log to an error logging client here } const ui = ( <ErrorBoundary FallbackComponent={ErrorFallback} onError={myErrorHandler}> <ComponentThatMayError /> </ErrorBoundary>, )You can also use it as a higher-order component:
import {withErrorBoundary} from 'react-error-boundary' const ComponentWithErrorBoundary = withErrorBoundary(ComponentThatMayError, { FallbackComponent: ErrorBoundaryFallbackComponent, onError(error, componentStack) { // Do something with the error // E.g. log to an error logging client here }, }) const ui = <ComponentWithErrorBoundary />Often you may want to recover from the error. You can do this using the resetErrorBoundary prop:
function ErrorFallback({error, resetErrorBoundary}) { return ( <div role="alert"> <div>Oh no</div> <pre>{error.message}</pre> <button onClick={resetErrorBoundary}>Try again</button> </div> ) }However, normally "trying again" like that will just result in the user experiencing the same error. Typically some other state in your app will need to be reset as well. The problem is, the ErrorFallback component won't usually have access to the state that needs to be reset.
So alternatively, you can use the fallbackRender prop:
const ui = ( <ErrorBoundary fallbackRender={({error, resetErrorBoundary}) => ( <div role="alert"> <div>Oh no</div> <pre>{error.message}</pre> <button onClick={() => { resetComponentState() // <-- this is why the fallbackRender is useful resetErrorBoundary() }} > Try again </button> </div> )} > <ComponentThatMayError /> </ErrorBoundary> )I know what you're thinking: I thought we ditched render props when hooks came around. Unfortunately, the current React Error Boundary API only supports class components at the moment, so render props are the best solution we have to this problem.
In the spirit of consistency with the React.Suspense component, we also support a simple fallback prop which you can use for a generic fallback. This will not be passed any props so you can't show the user anything actually useful though, so it's not really recommended.
const ui = ( <ErrorBoundary fallback={<div>Oh no</div>}> <ComponentThatMayError /> </ErrorBoundary> )Looking to contribute? Look for the Good First Issue label.
Please file an issue for bugs, missing documentation, or unexpected behavior.
Please file an issue to suggest new features. Vote on feature requests by adding a π. This helps maintainers prioritize what to work on.
MIT