83

How can we implement error Boundary in React Hooks. Is it even supported with react Hooks?

7 Answers 7

47

The questions is whether it is possible to implement Error Boundary as a hook and the answer is no BUT it does not mean that you can not use Error Boundary class components in a project which you use hooks heavily.

Create a Error Boundary class component and wrap your React Functional Components(hooks) with the Error Boundary class component.

Sign up to request clarification or add additional context in comments.

3 Comments

This advice is perfect. Saw the same happening on a big production example and will implement the same in my project as well.
This throws a Renedered fewer hooks than expected error for me, because the hooks are behind a conditional statement.
For those of us who love the functional programming of React and Hooks, this option makes us sad "It must be a class component 🙁".
29

You can implement error boundary in react hooks with the help of react-error-boundary package.

npm install --save react-error-boundary

Then:

import {ErrorBoundary} from 'react-error-boundary'

function ErrorFallback({error, resetErrorBoundary}) {
  return (
    <div role="alert">
      <p>Something went wrong:</p>
      <pre>{error.message}</pre>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  )
}

const ui = (
  <ErrorBoundary
    FallbackComponent={ErrorFallback}
    onReset={() => {
      // reset the state of your app so the error doesn't happen again
    }}
  >
    <ComponentThatMayError />
  </ErrorBoundary>
)

Please read more on React-error-boundary

1 Comment

Note that this react-error-boundary looks like as good as you're gonna get until they officially support it in react. This library is written by Brian Vaughn who worked on React Dev Tools at Facebook. There's also a nice blog post from Kent Dodds about Use react-error-boundary to handle errors in React
19

*There is no Error Boundaries in hook yet *

componentDidCatch 
and 
getDerivedStateFromError 

There are no Hook equivalents for these methods yet, but they will be added soon.

3 Comments

That's what it was said when hooks were released in 2018; it's almost 2022 and no sign of this getting fixed.
Today is in 2022.
There is not any official hook for that , its been 2023. but you can simply use try...catch to catch component errors like this:
12

I wrote react-use-error-boundary to achieve this.

React 16 introduced Error Boundaries. As of React 17, there still is not an equivalent hook for function components.

I liked the API implemented by Preact's useErrorBoundary and attempted to recreate a similar API. If you're interested in building this from scratch you can checkout the code on GitHub.

Comments

11

You can't do that with hooks. Hooks do not have an equivalent of componentDidCatch. See this section of the hook FAQ

  • getSnapshotBeforeUpdate, componentDidCatch and getDerivedStateFromError: There are no Hook equivalents for these methods yet, but they will be added soon.

1 Comment

This is useful purely because you mention the exact part of the FAQ that is missing componentDidCatch. In the FAQ they don't refer to 'Error Boundaries', all other answers here are assuming you know Error Boundaries means componentDidCatch.
0

For React v18.3.1 and above.

Replace AddCommentButton with App component.

import { useTransition } from "react";
import { ErrorBoundary } from "react-error-boundary";

export function AddCommentContainer() {
  return (
    <ErrorBoundary fallback={<p>⚠️Something went wrong</p>}>
      <AddCommentButton />
    </ErrorBoundary>
  );
}

function addComment(comment) {
  // For demonstration purposes to show Error Boundary
  if (comment == null) {
    throw new Error("Example Error: An error thrown to trigger error boundary");
  }
}

function AddCommentButton() {
  const [pending, startTransition] = useTransition();

  return (
    <button
      disabled={pending}
      onClick={() => {
        startTransition(() => {
          // Intentionally not passing a comment
          // so error gets thrown
          addComment();
        });
      }}
    >
      Add comment
    </button>
  );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>

Comments

-1

how about this:

import React, { useState, useEffect } from 'react';

function ErrorBoundary(props) {
  const [error, setError] = useState(null);
  
  useEffect(() => {
    // Catch errors thrown by child components
    const handleErrors = (err) => {
      setError(err);
    };
    window.addEventListener('error', handleErrors);
    return () => {
      window.removeEventListener('error', handleErrors);
    };
  }, []);
  
  if (error) {
    return <h1>Something went wrong: {error.message}</h1>;
  }
  
  return props.children;
}

export default ErrorBoundary;

2 Comments

This falls short of a typical ErrorBoundry's ability to catch errors locally. Consider the potential need of many ErrroBoundry locations - this pattern you suggest would not be compatible. In my opinion this solution is an anti pattern when we have the class implementation available to us.
window.addEventListener('error', ...) doesn't catch uncaught errors, read about what it's actually for developer.mozilla.org/en-US/docs/Web/API/Window/error_event.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.