DEV Community

Cover image for Data Fetching in React
Agbo, Daniel Onuoha
Agbo, Daniel Onuoha

Posted on

Data Fetching in React

Data fetching is fundamental in React applications, powering functionality like loading user data, rendering content dynamically, and more. React offers a flexible ecosystem for data handling, with various libraries and approaches to choose from depending on the complexity and performance needs of your app. In this article, we'll explore several key methods for data fetching in React, including the Fetch API, Axios, Async/Await, React Query, SWR, and GraphQL.


1. Fetching Data with the Fetch API

The Fetch API is a built-in web API that makes network requests simpler and is widely supported by modern browsers. It returns a Promise that resolves with a Response object representing the data from the API request.

Example

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

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

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('https://jsonplaceholder.typicode.com/posts');
        if (!response.ok) throw new Error('Network response was not ok');
        const data = await response.json();
        setData(data);
      } catch (error) {
        setError(error.message);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, []);

  return (
    <div>
      {loading ? <p>Loading...</p> : data.map((item) => <p key={item.id}>{item.title}</p>)}
      {error && <p>Error: {error}</p>}
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

When to Use the Fetch API

  • Small projects or those with basic data-fetching needs.
  • Minimal dependencies and compatibility with browser-based apps.

2. Using Axios for Data Fetching

Axios is a promise-based HTTP client for the browser and Node.js that offers more features than the Fetch API, like request and response interceptors and the ability to transform requests and responses.

Example

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

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

  useEffect(() => {
    axios
      .get('https://jsonplaceholder.typicode.com/posts')
      .then((response) => {
        setData(response.data);
        setLoading(false);
      })
      .catch((error) => {
        setError(error.message);
        setLoading(false);
      });
  }, []);

  return (
    <div>
      {loading ? <p>Loading...</p> : data.map((item) => <p key={item.id}>{item.title}</p>)}
      {error && <p>Error: {error}</p>}
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Benefits of Axios

  • Supports older browsers that may not fully support the Fetch API.
  • Offers better error handling by rejecting on HTTP error codes.
  • Allows easy request and response transformations, making it popular for larger, more complex applications.

3. Using Async/Await Syntax for Better Readability

With async and await, handling asynchronous code in JavaScript has become much cleaner. Both the Fetch API and Axios can be used with async/await syntax to make the code easier to read.

Example with Fetch

const fetchData = async () => {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts');
    const data = await response.json();
    setData(data);
  } catch (error) {
    console.error('Error fetching data:', error);
  }
};
Enter fullscreen mode Exit fullscreen mode

Benefits of Async/Await

  • Improves readability and is easier to handle than promise chains.
  • Allows us to use try/catch blocks for error handling.

4. React Query: A Powerful Data Fetching and Caching Library

React Query handles caching, synchronization, and updates of server state, enabling you to fetch, update, and cache data with ease. React Query's automatic data caching and re-fetching make it a popular choice for complex applications.

Example

import React from 'react';
import { useQuery } from 'react-query';
import axios from 'axios';

const fetchPosts = async () => {
  const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
  return response.data;
};

const ReactQueryExample = () => {
  const { data, isLoading, error } = useQuery('posts', fetchPosts);

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <div>
      {data.map((item) => (
        <p key={item.id}>{item.title}</p>
      ))}
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Benefits of React Query

  • Data caching and background refreshing.
  • Integrates well with APIs and handles retry logic for network failures.
  • Reduces code for managing loading, error, and re-fetching states.

5. SWR (Stale-While-Revalidate) from Vercel

SWR is another data fetching library that prioritizes cache and revalidation strategies. Developed by Vercel, SWR keeps data fresh by automatically re-fetching it in the background whenever the user revisits the page.

Example

import React from 'react';
import useSWR from 'swr';
import axios from 'axios';

const fetcher = (url) => axios.get(url).then((res) => res.data);

const SwrExample = () => {
  const { data, error } = useSWR('https://jsonplaceholder.typicode.com/posts', fetcher);

  if (!data) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <div>
      {data.map((item) => (
        <p key={item.id}>{item.title}</p>
      ))}
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Benefits of SWR

  • Uses cache-first data fetching with automatic background revalidation.
  • Integrates with popular backend frameworks and RESTful APIs.
  • Ideal for applications that need to keep data fresh with minimal code.

6. Fetching Data with GraphQL

GraphQL is a query language for APIs that provides more control over the data returned. It allows you to fetch only the fields you need, which can improve performance by reducing over-fetching or under-fetching.

Example with Apollo Client

To get started with Apollo Client, install it by running npm install @apollo/client graphql.

import React from 'react';
import { useQuery, gql } from '@apollo/client';

const GET_POSTS = gql`
  query GetPosts {
    posts {
      id
      title
    }
  }
`;

const GraphQLExample = () => {
  const { loading, error, data } = useQuery(GET_POSTS);

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

  return (
    <div>
      {data.posts.map((post) => (
        <p key={post.id}>{post.title}</p>
      ))}
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Benefits of GraphQL

  • Enables more efficient data fetching with control over fields retrieved.
  • Reduces network load, especially beneficial for complex or nested data.
  • Integrates well with libraries like Apollo Client, improving the developer experience.

Conclusion

Choosing the right method for data fetching in React depends on your project’s complexity, performance needs, and your preference for libraries and tools. Here’s a quick summary:

  • Fetch API: Good for small projects; built-in and minimal.
  • Axios: More advanced HTTP client with better error handling.
  • Async/Await: Improves readability and manageability of asynchronous code.
  • React Query: Excellent for caching, background re-fetching, and server-state management.
  • SWR: Stale-while-revalidate strategy, ideal for fresh data fetching.
  • GraphQL with Apollo: Best for complex data requirements where you need specific fields.

Top comments (0)