DEV Community

Cover image for How to Fetch Data Using Axios and React Query in ReactJS
Rifky Alfarez
Rifky Alfarez

Posted on

How to Fetch Data Using Axios and React Query in ReactJS

Fetching data is a fundamental part of building dynamic web applications, and tools like Axios and React Query make it easier to handle this task effectively in React.js applications. In this article, we’ll explore how to use Axios and React Query to simplify the process of fetching and managing data in React applications. By the end, you’ll understand why these tools are so popular and how they can boost the efficiency and maintainability of your code.

What is Axios and React Query?

Axios is a lightweight and feature-rich JavaScript library for making HTTP requests. It simplifies API interactions with features like interceptors, request cancellation, and response transformation.

React Query is a state management library designed for handling server state in React. It automates data fetching, caching, and synchronization, making it easier to manage and display API data efficiently.

Why Should You Use Axios and React Query?

Using Axios and React Query together streamlines data fetching and state management in React applications. Axios provides flexibility for making HTTP requests with features like custom headers and interceptors, while React Query simplifies server state handling with built-in caching, automated refetching, and background synchronization. This combination reduces boilerplate code, enhances user experience, and ensures your application is efficient and maintainable.

Let’s get started with a simple project with React JS.

Step 1: Set up the project and install the required libraries

To get started, set up a new React project using Vite for a fast and efficient development environment. Run the following command to create a new Vite project:

npm create vite@latest your-project-name
Enter fullscreen mode Exit fullscreen mode

Follow the prompts to choose a project name and select React with either JavaScript or TypeScript, depending on your preference. After the project is created, navigate to the project directory:

cd your-project-name
npm install
Enter fullscreen mode Exit fullscreen mode

Next, install Axios and React Query, as these are the libraries we’ll be using:

npm install axios @tanstack/react-query
Enter fullscreen mode Exit fullscreen mode

optional: If you prefer using Tailwind CSS for styling, you can remove the default styles provided by Vite and install Tailwind CSS for styling.

Step 2: Implement QueryClient from React Query

After installing the required libraries, the next step is to set up the QueryClient provided by React Query. This client acts as the core of React Query, managing queries and caching. It's best practice to place the QueryClientProvider at the top-level component to make React Query accessible throughout your application.

Here’s how you can modify your app.tsx file:

//app.tsx

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import './App.css';
import ProductList from './components/ProductList';

const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <main className="bg-neutral-50 min-h-screen">
        <div className="w-[1020px] mx-auto py-4">
          <h1 className="text-[2rem] text-neutral-950 font-bold">
            React Query with Axios
          </h1>
          <ProductList />
        </div>
      </main>
    </QueryClientProvider>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Step 3: Create API and Components Folders

Organize your project structure by creating the following folders and files:

  • src/api/fakeStoreApi.ts for handling data fetching with Axios.
  • src/components/ProductList.tsx for displaying the fetched data.

so the result will be like this:

project structure

Step 4: Create an API Service for Fetching Data with Axios

In this step, we create a dedicated service file to manage all API interactions efficiently. For this tutorial, we’ll be using the Fake Store API.

in fakeStoreApi.ts :

//fakeStoreApi.ts

import axios from 'axios';

const BASE_URL = 'https://fakestoreapi.com';

const axiosInstance = axios.create({
  baseURL: BASE_URL,
});

export const getAllProducts = async () => {
  try {
    const response = await axiosInstance.get('/products');
    return response.data;
  } catch (error) {
    console.error(error);
    return null;
  }
};
Enter fullscreen mode Exit fullscreen mode
  • Base URL Configuration:
    Utilizes axios.create to set up an Axios instance with a default baseURL. This ensures all HTTP requests use the base URL https://fakestoreapi.com.

  • Reusable API Function:
    The getAllProducts function is created to fetch product data from the /products endpoint. This function can be reused across various components in the application.

  • Error Handling:
    Implements a try...catch block to manage errors during API calls. If an error occurs, it logs the error to the console and returns null to avoid breaking the application.

Step 5: Display the Products List in a Component

In this step, we create a ProductList component to fetch and display product data using React Query. The component will utilize the getAllProducts function from our API service to retrieve data and then render the products.

in ProductList.tsx:

//ProductList.tsx

import { useQuery } from '@tanstack/react-query';
import { getAllProducts } from '../api/fakeStoreApi';

type ProductsProps = {
  id: number;
  title: string;
  price: number;
  category: string;
  description: string;
  image: string;
};

export default function ProductList() {
  const { data } = useQuery({
    queryKey: ['products'],
    queryFn: getAllProducts,
  });

  return (
    <div>
      {data?.map((product: ProductsProps) => (
        <div key={product.id}>
          <h2>{product.title}</h2>
        </div>
      ))}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

and it will look like this:
fetch result

then let's add some styling to make it more aesthetic.

//ProductList.tsx

import { useQuery } from '@tanstack/react-query';
import { getAllProducts } from '../api/fakeStoreApi';

type ProductsProps = {
  id: number;
  title: string;
  price: number;
  category: string;
  description: string;
  image: string;
};

export default function ProductList() {
  const { data } = useQuery({
    queryKey: ['products'],
    queryFn: getAllProducts,
  });

  return (
    <div>
      <h2 className="text-[1.2rem] text-neutral-900 font-semibold pb-2">
        Product List:
      </h2>
      <div className="grid grid-cols-4 gap-4">
        {data?.map((product: ProductsProps) => (
          <div
            key={product.id}
            className="bg-neutral-200 rounded-lg flex flex-col gap-y-2 p-2"
          >
            <img
              src={product.image}
              alt={product.title}
              className="w-full h-[300px] object-cover rounded-md"
            />
            <div>
              <p className="text-[0.8rem] text-neutral-600">
                {product.category}
              </p>
              <h3 className="text-[1rem] text-neutral-800 font-medium">
                {product.title.length > 20
                  ? `${product.title.slice(0, 20)}...`
                  : product.title}
              </h3>
            </div>
            <p className="text-[0.9rem] text-neutral-800">${product.price}</p>
          </div>
        ))}
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

so the final display will look like this:

Final looks

and also you can add isLoadingand errorstates for a better user experience.

//ProducList.tsx
import { useQuery } from '@tanstack/react-query';
import { getAllProducts } from '../api/fakeStoreApi';

type ProductsProps = {
  id: number;
  title: string;
  price: number;
  category: string;
  description: string;
  image: string;
};

export default function ProductList() {
  const { data, isLoading, error } = useQuery({
    queryKey: ['products'],
    queryFn: getAllProducts,
  });

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

  return (
    <div>
      <h2 className="text-[1.2rem] text-neutral-900 font-semibold pb-2">
        Product List:
      </h2>
      <div className="grid grid-cols-4 gap-4">
        {data?.map((product: ProductsProps) => (
          <div
            key={product.id}
            className="bg-neutral-200 rounded-lg flex flex-col gap-y-2 p-2"
          >
            <img
              src={product.image}
              alt={product.title}
              className="w-full h-[300px] object-cover rounded-md"
            />
            <div>
              <p className="text-[0.8rem] text-neutral-600">
                {product.category}
              </p>
              <h3 className="text-[1rem] text-neutral-800 font-medium">
                {product.title.length > 20
                  ? `${product.title.slice(0, 20)}...`
                  : product.title}
              </h3>
            </div>
            <p className="text-[0.9rem] text-neutral-800">${product.price}</p>
          </div>
        ))}
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

I hope this tutorial has helped you understand how to use Axios and React Query effectively in a React application. By mastering these tools, you can build more robust, efficient, and scalable applications. I encourage you to explore their advanced features and adapt them to suit your specific project needs. You’ll find the project in my github. See you, Thanks guys!

Top comments (2)

Collapse
 
philip_zhang_854092d88473 profile image
Philip

Thanks for the tutorial! Axios and React Query are a powerful combination for efficient data fetching and state management. By using EchoAPI, you can streamline API testing and mocking, ensuring smoother integration with React Query and improving app reliability. Check out EchoAPI echoapi.com/.

Collapse
 
difani_anjayani_ffbd2fd3c profile image
Difani Anjayani

thanks for sharing✊❤‍🔥,, proud of uuuu🥰

Some comments may only be visible to logged-in visitors. Sign in to view all comments.