Blog>
Snippets

Structuring Error Handling in Data Fetching

Explain how to structure error handling using try/catch within asynchronous data fetching calls in React components, ensuring a robust user experience.
import React, { useState, useEffect } from 'react';

async function fetchData(url) {
  try {
    let response = await fetch(url);
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    let data = await response.json();
    return data;
  } catch (error) {
    throw error;
  }
}

const DataFetcher = ({ url }) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetchData(url)
      .then(data => {
        setData(data);
        setLoading(false);
      })
      .catch(error => {
        setError(error.message);
        setLoading(false);
      });
  }, [url]);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.body}</p>
    </div>
  );
};
This code demonstrates how to structure error handling within asynchronous data fetching calls in React components. It defines an asynchronous function `fetchData` that fetches data from a given URL and uses try/catch for error handling. The custom React component `DataFetcher` uses the `useState` and `useEffect` hooks to manage the data fetching process, including setting loading and error states based on the outcome of the fetch operation. If an error occurs during the fetch operation, the catch block is executed, and the error is thrown, which is then caught in the `.catch` chain of the promise in the useEffect. This pattern ensures that any networking errors are appropriately handled, providing a robust user experience by displaying informative messages based on the component's state.