React js: API calling - GET method

Last updated: July 18, 2023

API calls are a common requirement in modern web development, and React.js provides a powerful framework for building applications that interact with APIs. In this article, we will delve into making API calls using the GET method in React.js. We will explore various techniques, best practices, and code examples to help you harness the full potential of API integration in your React.js projects.

 

Understanding the GET Method

The GET method is one of the most commonly used HTTP methods. It is used to retrieve or fetch data from a specified resource on a server. When a client (such as a web browser or a client-side application) sends a GET request to a server, it expects the server to return the requested data in the response.

Here are some key characteristics of the GET method in HTTP:

  • Safe and Idempotent: The GET method is considered safe, meaning it should not modify any data on the server. It retrieves data without causing any side effects. Additionally, multiple identical GET requests should produce the same result (i.e., they are idempotent), allowing them to be repeated without changing the server's state.
  • URL-Based: The GET request includes the URL (Uniform Resource Locator) of the resource to be fetched. The URL can contain query parameters to specify additional details about the request, such as filters, sorting criteria, or pagination.
  • Query Parameters: GET requests can pass query parameters as part of the URL. These parameters are appended to the URL after a question mark (?) and are separated by ampersands (&). Query parameters allow clients to customize the data they want to retrieve from the server.
  • Response: When the server receives a GET request, it processes the request, retrieves the requested resource, and includes it in the response. The response typically includes a status code (indicating the success or failure of the request), headers with metadata, and the requested data in the response body.

Common use cases of the GET method:

  1. Fetching web pages
  2. Retrieving data from APIs
  3. Accessing static files
  4. Performing read operations in RESTful API architectures

It's important to note that while the GET method is suitable for retrieving data, it is not recommended for sending sensitive information like passwords or other confidential data. In such cases, other HTTP methods like POST or PUT should be used with appropriate security measures.

 

Making GET Requests with Fetch API

The Fetch API is a built-in web API in modern browsers that provides a straightforward way to make HTTP requests. Here, we explore the steps involved in making GET requests using the Fetch API in React.js.

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

const ApiGet =  () => {

  const [data, setData] = useState(null);
 
  const fetchData=async ()=>{
    try {
      const response = await fetch('https://jsonplaceholder.typicode.com/users');
      if (!response.ok) {
        throw new Error('Network response was not OK');
      }
      setData(await response.json());
      
    } catch (error) {
      console.error('Error:', error);
    }

  }
  useEffect(()=>{
    fetchData();
  },[])
  
  return (
    <div>
      <h2>GET Method</h2>
      {data ? (
        <ul>
          {data.map((item) => (
            <li key={item.id}>{item.name}</li>
          ))}
        </ul>
      ) : (
        <p>Loading data...</p>
      )}
    </div>
  );
}

export default ApiGet

In this code example, we have a functional component called ApiGet. This component is responsible for fetching data from the JSONPlaceholder API using the GET method. The component imports the necessary modules from the React library, including the useEffect and useState hooks.

Inside the component, we have a state variable called data, which is initialized to null using the useState hook. This state variable will hold the retrieved data from the API.

The component defines an asynchronous function called fetchData. This function is responsible for making the GET request using the fetch function provided by the browser's Fetch API. Inside the function, we use the await keyword to pause the execution and wait for the response from the server.

Once the response is received, we check if it is successful by examining the response.ok property. If the response is not ok, we throw an error using the throw statement.

If the response is successful, we use the response.json() method to parse the response data as JSON. We then use await to extract the JSON data and update the data state using the setData function from the useState hook.

To trigger the data fetching, the component utilizes the useEffect hook. The useEffect hook is called with a callback function that invokes the fetchData function when the component mounts. The empty dependency array ([]) passed as the second argument ensures that the effect runs only once.

In the JSX rendering, we conditionally render the retrieved data. If the data state is not null, we map over the data array and render a list of <li> elements, displaying the name property for each item. Each <li> element is assigned a unique key using the item.id.

On the other hand, if the data state is null, a "Loading data..." message is displayed to indicate that the data is being fetched.

Finally, the ApiGet component is exported as the default export of the module, making it available for use in other parts of the application.

In summary, this code showcases how to use React hooks, specifically the useEffect and useState hooks, to perform a GET request using the Fetch API. The retrieved data is stored in the component's state and rendered in the JSX.

 

Making GET Requests with Axios:

To use Axios in our React project, we need to install it first. Open your terminal and run the following command:

npm install axios

Now we can use axios in our code:

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

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

  const fetchData = async () => {
    try {
      const response = await axios.get('https://jsonplaceholder.typicode.com/users');
      setData(response.data);
      setLoading(false);
    } catch (error) {
      setError(error);
      setLoading(false);
    }
  };
  useEffect(() => {
    fetchData();
  }, []);


  if (loading) {
    return <p>Loading data...</p>;
  }


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

  return (
    <>
    <h2>GET method with axios </h2>
    <ul>
      {data.map((item) => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
    </>
  );
};

export default ApiGetAxios;


In this example, we define an asynchronous function fetchData using the async/await syntax. Inside the function, we use await to wait for the response from the API call using axios.get. The response data is then set to the data state using the setData function.

Within the useEffect hook, we call the fetchData function to fetch the data when the component mounts. Any errors that occur during the API call are caught in the catch block and set to the error state.

The component renders a loading message while the data is being fetched (loading state is true). If an error occurs during the API call, an error message is displayed (error state is not null). Once the data is successfully retrieved, it is rendered as a list of items.

 

Best Practices:

  • Use Asynchronous Patterns: Asynchronous patterns like Promises or async/await allow you to handle API calls more effectively. They provide a way to handle the response and error scenarios without blocking the main thread, ensuring a smooth user experience.
  • Separate API Logic: To maintain clean and organized code, it's recommended to separate the API logic from the components. Create a dedicated module or service responsible for making API calls, encapsulating all the necessary logic such as constructing the URL, headers, and handling responses. This promotes reusability and simplifies maintenance.
  • Handle Loading States: Display loading indicators or placeholders while the API call is in progress. This provides visual feedback to users, indicating that data is being fetched. You can use boolean flags like isLoading or loading in the component's state to track the loading state.
  • Implement Error Handling: API calls can fail due to various reasons, such as network issues or incorrect request parameters. Ensure you handle errors appropriately and provide meaningful error messages to users. Use try/catch blocks or .catch() handlers to catch and handle errors. You can set an error state variable and display error messages in the UI.
  • Implement Caching Mechanisms: Consider implementing caching mechanisms to store previously fetched API data, especially if the data doesn't change frequently. Caching can help reduce unnecessary API calls, improve performance, and minimize network bandwidth usage. Libraries like react-query or browser mechanisms like localStorage or sessionStorage can be useful for caching data.
  • Use Debouncing and Throttling Techniques: If your application involves frequent API calls triggered by user actions, consider implementing debouncing or throttling techniques to optimize the number of requests sent to the server. Debouncing limits the number of calls made within a specified time interval, while throttling limits the frequency of API calls. These techniques prevent excessive API requests and improve performance.
  • Cancel Pending Requests: In scenarios where users rapidly navigate between components or initiate multiple API calls within a short time, it's important to cancel any pending or ongoing requests to prevent unnecessary data fetching. Libraries like axios provide cancellation tokens or you can use the AbortController API for canceling requests.
  • Handle Pagination: If your API supports pagination, handle it appropriately. Implement mechanisms to load additional data when the user requests more items, such as scrolling to the bottom of a list or clicking a "Load More" button. Proper pagination ensures efficient data retrieval without overwhelming the UI.
  • Implement Optimistic UI Updates: In situations where you're performing an API call that updates data on the server, consider implementing optimistic UI updates. This involves updating the UI optimistically before receiving the response from the server, improving perceived performance. If the API call fails, you can handle the error and roll back the UI changes.
  • Test and Monitor API Calls: Thoroughly test your API calls and ensure they work as expected in different scenarios. Monitor your API calls for performance, error rates, and other metrics using tools like browser dev tools or specialized monitoring solutions. This allows you to identify and address any issues related to API performance or reliability.

 

Related post