DEV Community

Cover image for Make Errors User-Friendly with React Error Boundaries
Thisura Thenuka
Thisura Thenuka

Posted on • Originally published at simplecoder.hashnode.dev

Make Errors User-Friendly with React Error Boundaries

What are Error Boundaries ?

React Error Boundaries are used to show a user-friendly UI to users when unexpected JavaScript errors occur.

A JavaScript error in a part of the UI usually renders a white screen and crashes the entire app. React Version 16 introduced a solution to this issue with the new “Error Boundary” concept.

How can I implement Error Boundaries ?

You can implement React Error Boundaries in your React app in 2 simple steps

  1. Create an error boundary component
  2. Wrap error-prone component with error boundary component

Creating Error Boundary Component

A class component becomes an error boundary if it defines either (or both) of the lifecycle methods static getDerivedStateFromError() or componentDidCatch(). Use static getDerivedStateFromError() to render a fallback UI after an error has been thrown. Use componentDidCatch() to log error information. (https://reactjs.org/docs/error-boundaries.html)

Here is the example error boundary component provided in the React documentation.

import React from "react";

class ErrorBoundary extends React.Component {
    constructor(props) {
      super(props);
      this.state = { error: null, errorInfo: null };
    }

    componentDidCatch(error, errorInfo) {
      // Catch errors in any components below and re-render with error message
      this.setState({
        error: error,
        errorInfo: errorInfo
      })
      // You can also log error messages to an error reporting service here
    }

    render() {
      if (this.state.errorInfo) {
        // Error path
        return (
          <div>
            <h2>Something went wrong.</h2>
            <details style={{ whiteSpace: 'pre-wrap' }}>
              {this.state.error && this.state.error.toString()}
              <br />
              {this.state.errorInfo.componentStack}
            </details>
          </div>
        );
      }
      // Normally, just render children
      return this.props.children;
    }  
  }

export default ErrorBoundary;
Enter fullscreen mode Exit fullscreen mode

You can create your own error boundary with a fancier UI according to your use case.

Wrapping with Error Boundary

wrapping-with-error-boundary

There are two ways you could wrap components with the error boundary

  1. You can wrap the top-level component
  2. You can wrap individual components

Wrapping Top-Level Component

<ErrorBoundary>
    <App/>
</ErrorBoundary>
Enter fullscreen mode Exit fullscreen mode

error-boundaries-for-root

Wrapping Individual Components

This approach would be ideal if your app has multiple different isolated sections.

<ErrorBoundary>
    <BankingController/>
</ErrorBoundary>
<ErrorBoundary>
    <ProfileController/>
</ErrorBoundary>
<ErrorBoundary>
    <PolicyController/>
</ErrorBoundary>
Enter fullscreen mode Exit fullscreen mode

An error occurred in BankingController would not stop user from using the PolicyController or ProfileController.

error-boundaries-for-individual

So, Is my React app “white screen”-free now?

wow-image

Well, React error boundaries can catch all errors except for the following :

  1. Event Handlers
  2. Asynchronous code
  3. Server Side Rendering
  4. Errors thrown in the error boundary itself

But you can always make use of regular JavaScript try/catch blocks whenever needed.

As of React 16, errors that were not caught by any error boundary will result in unmounting of the whole React component tree

Conclusion

React error boundaries provide a way for developers to make our apps more user-friendly. In my opinion, every React app should make use of React error boundaries and it makes a drastic difference in the user experience.

Thank you for taking the time to read my article. Hope you enjoyed it. If you learned something new, make sure to drop a like and share the article with your fellow developers.

Top comments (0)