Error handling in React data fetching with error boundaries

When building a React application that fetches data from an API, error handling becomes an important aspect of the development process. Without proper error handling, a failed API call can result in a broken user experience.

React provides the concept of “Error Boundaries” to handle and display errors within components. Error Boundaries catch JavaScript errors anywhere in their child component tree and display a fallback UI instead of crashing the whole application.

In this blog post, we will explore how to handle errors in data fetching using Error Boundaries in React.

1. Setting up Error Boundaries

To start using Error Boundaries, follow these steps:

  1. Create a new component called 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 };
  }

  componentDidCatch(error, errorInfo) {
    // You can log the error to an error reporting service
    console.error(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <div>Something went wrong!</div>;
    }

    return this.props.children;
  }
}

export default ErrorBoundary;
  1. Wrap the component or components where the data fetching is being performed inside the ErrorBoundary component:
import React from 'react';
import ErrorBoundary from './ErrorBoundary';

function MyComponent() {
  return (
    <ErrorBoundary>
      {/* Perform data fetching */}
    </ErrorBoundary>
  );
}

export default MyComponent;

2. Handling Errors in Data Fetching

To handle errors in data fetching, you can use the try...catch statement. Here’s an example using the fetch API:

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

function MyComponent() {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('https://api.example.com/data');
        const result = await response.json();
        setData(result);
      } catch (error) {
        setError(error);
      }
    };

    fetchData();
  }, []);

  if (error) {
    throw error;
  }

  if (!data) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      {/* Render data */}
    </div>
  );
}

export default MyComponent;

In this example, if an error occurs during the data fetching process, it is caught using the catch block and stored in the error state. If there is an error, it is thrown outside of the component, and the Error Boundary component will handle and display the error message.

3. Customizing Error Boundary UI

You can customize the UI of the Error Boundary component to suit your needs. Modify the render method in the ErrorBoundary component to display a more user-friendly error message or UI.

For example, you can render a fallback UI with a button to reload the page:

render() {
  if (this.state.hasError) {
    return (
      <div>
        <h1>Something went wrong!</h1>
        <button onClick={() => window.location.reload()}>Reload</button>
      </div>
    );
  }

  return this.props.children;
}

Conclusion

By implementing Error Boundaries in your React application, you can gracefully handle errors that occur during data fetching. This prevents the entire application from crashing and provides a better user experience.

Remember to wrap your components performing data fetching with the ErrorBoundary component and handle errors appropriately using try…catch blocks. Customize the UI of the ErrorBoundary component to provide relevant error messages or fallback UIs.

#react #errorhandling