A Beginner's Guide to Error Boundaries in React

A Beginner's Guide to Error Boundaries in React

In React, Error Boundaries are a way to catch and handle errors that occur during the rendering process of a component tree. This helps to prevent the entire application from crashing due to a single error. In this article, we'll go over the basics of Error Boundaries and provide an example of how to use them in a React component.

Let's start by creating a new React component called "ErrorBoundary" that will be our error boundary. The ErrorBoundary component will have a state property called "hasError" that will be set to false by default. If an error occurs during the rendering process of its child components, the "hasError" property will be set to true and an error message will be displayed to the user.

Here is the code for the ErrorBoundary component:

import React from "react";

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

export default ErrorBoundary;

In this code, we define the ErrorBoundary component as a class component. In its constructor, we set the initial state of "hasError" to false.

The getDerivedStateFromError() is a lifecycle method that is called whenever an error is thrown by the child components of the ErrorBoundary. It returns a new state that will update the hasError property to true.

In the render() method, we check if the hasError property is true. If it is, we display an error message. Otherwise, we return the child components of the ErrorBoundary using the props.children property.

Now, let's create a child component called "Counter" that will simply display a number and increment it when a button is clicked.

import React from "react";

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState((state) => ({ count: state.count + 1 }));
  }

  render() {
    if (this.state.count === 5) {
      throw new Error("Oops!");
    }
    return (
      <div>
        <h2>Count: {this.state.count}</h2>
        <button onClick={this.handleClick}>Increment</button>
      </div>
    );
  }
}

export default Counter;

In this code, we define the Counter component as a class component. In its constructor, we set the initial state of "count" to 0 and bind the handleClick() method to the component's this context.

In the render() method, we check if the count property is equal to 5. If it is, we throw an error by using the throw keyword with a new Error object.

Now, let's use these components in a parent component called "App" and wrap the Counter component inside the ErrorBoundary component.

import React from "react";
import ErrorBoundary from "./ErrorBoundary";
import Counter from "./Counter";

const App = () => {
  return (
    <div>
      <ErrorBoundary>
        <Counter />
      </ErrorBoundary>
    </div>
  );
};

export default App;

In this code, we import both the ErrorBoundary and Counter components and wrap the Counter component inside the ErrorBoundary component. This means that if an error is thrown by the Counter component, it will be caught by the ErrorBoundary and the error message will be displayed instead of crashing the entire application.

To replicate this example in your local machine, follow these steps:

  1. Create a new React project by running the following command in your terminal:

     npx create-react-app my-app
    
  2. Change your directory to the newly created project by running the following command:

     cd my-app
    
  3. Replace the contents of the src folder with the following files:

    • src/App.js

        import React from "react";
        import ErrorBoundary from "./ErrorBoundary";
        import Counter from "./Counter";
      
        const App = () => {
          return (
            <div>
              <ErrorBoundary>
                <Counter />
              </ErrorBoundary>
            </div>
          );
        };
      
        export default App;
      
    • src/ErrorBoundary.js

        import React from "react";
      
        class ErrorBoundary extends React.Component {
          constructor(props) {
            super(props);
            this.state = { hasError: false };
          }
      
          static getDerivedStateFromError(error) {
            return { hasError: true };
          }
      
          render() {
            if (this.state.hasError) {
              return <h1>Something went wrong.</h1>;
            }
            return this.props.children;
          }
        }
      
        export default ErrorBoundary;
      
    • src/Counter.js

        import React from "react";
      
        class Counter extends React.Component {
          constructor(props) {
            super(props);
            this.state = { count: 0 };
            this.handleClick = this.handleClick.bind(this);
          }
      
          handleClick() {
            this.setState((state) => ({ count: state.count + 1 }));
          }
      
          render() {
            if (this.state.count === 5) {
              throw new Error("Oops!");
            }
            return (
              <div>
                <h2>Count: {this.state.count}</h2>
                <button onClick={this.handleClick}>Increment</button>
              </div>
            );
          }
        }
      
        export default Counter;
      
  4. Start the development server by running the following command:

     npm start
    
  5. Open your browser and navigate to localhost:3000 to see the application in action.


Application Screenshots


In conclusion, Error Boundaries are an important tool for handling errors in React applications. They allow us to catch and handle errors that occur during the rendering process of a component tree, preventing the entire application from crashing due to a single error. By following the example provided in this article, you can easily incorporate Error Boundaries into your own React projects.