Module: API Integration

Using Axios

React JS: API Integration - Using Axios

Introduction

Integrating with APIs is a fundamental aspect of modern web development. React, being a front-end library, often needs to fetch data from and send data to back-end servers. Axios is a popular, promise-based HTTP client that simplifies making these requests. This document will guide you through integrating APIs in your React application using Axios.

Prerequisites

  • Node.js and npm (or yarn) installed: Ensure you have Node.js and its package manager installed on your system.
  • Basic React knowledge: Familiarity with React components, state, and lifecycle methods (or hooks) is assumed.
  • An API to work with: For demonstration, we'll use a public API like JSONPlaceholder. You can substitute this with your own API.

Installing Axios

First, install Axios into your React project using npm or yarn:

npm install axios
# or
yarn add axios

Making GET Requests

The most common API interaction is fetching data using a GET request. Here's how to do it using Axios within a React component:

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

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

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

    fetchData();
  }, []); // Empty dependency array ensures this effect runs only once on mount

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

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

  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.body}</p>
    </div>
  );
}

export default DataFetcher;

Explanation:

  1. Import Axios: import axios from 'axios'; imports the Axios library.
  2. State Variables:
    • data: Stores the fetched data. Initialized to null.
    • loading: Indicates whether the data is being fetched. Initialized to true.
    • error: Stores any error that occurs during the fetch. Initialized to null.
  3. useEffect Hook: This hook is used to perform side effects (like API calls) in functional components.
    • The empty dependency array [] ensures the effect runs only once when the component mounts.
  4. fetchData Function:
    • An async function to handle the API call.
    • axios.get('https://jsonplaceholder.typicode.com/posts/1'): Makes a GET request to the specified URL. Axios returns a Promise.
    • await: Pauses execution until the Promise resolves (the API call completes).
    • response.data: The actual data returned by the API is accessed through response.data.
    • setData(response.data): Updates the data state with the fetched data.
    • setLoading(false): Sets loading to false to indicate the data has been loaded.
    • Error Handling: The try...catch block handles potential errors during the API call. If an error occurs, it updates the error state and sets loading to false.
  5. Conditional Rendering: The component renders different content based on the loading and error states.

Making POST Requests

To send data to an API (e.g., creating a new resource), use a POST request.

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

function PostCreator() {
  const [title, setTitle] = useState('');
  const [body, setBody] = useState('');
  const [success, setSuccess] = useState(false);

  const handleSubmit = async (e) => {
    e.preventDefault();

    try {
      const response = await axios.post('https://jsonplaceholder.typicode.com/posts', {
        title: title,
        body: body,
        userId: 1,
      });

      console.log('Post created:', response.data);
      setSuccess(true);
      setTitle('');
      setBody('');
    } catch (error) {
      console.error('Error creating post:', error);
      setSuccess(false);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Title:
        <input type="text" value={title} onChange={(e) => setTitle(e.target.value)} />
      </label>
      <br />
      <label>
        Body:
        <input type="text" value={body} onChange={(e) => setBody(e.target.value)} />
      </label>
      <br />
      <button type="submit">Create Post</button>

      {success && <p>Post created successfully!</p>}
    </form>
  );
}

export default PostCreator;

Explanation:

  1. axios.post(): Makes a POST request to the specified URL.
  2. Data Payload: The second argument to axios.post() is the data you want to send to the API. It's typically an object.
  3. Form Handling: The component includes a form to collect user input (title and body).
  4. handleSubmit Function: Handles the form submission.
  5. Success State: The success state variable indicates whether the post was created successfully.

Other HTTP Methods

Axios supports other HTTP methods as well:

  • axios.put(): Used to update an existing resource.
  • axios.patch(): Used to partially update an existing resource.
  • axios.delete(): Used to delete a resource.

The usage is similar to axios.get() and axios.post(), with the appropriate method and potentially a data payload.

Axios Configuration

Axios allows you to configure default settings for your requests. This can be useful for setting base URLs, headers, or authentication tokens.

// axiosConfig.js
import axios from 'axios';

const instance = axios.create({
  baseURL: 'https://jsonplaceholder.typicode.com',
  timeout: 10000, // 10 seconds
  headers: {
    'Content-Type': 'application/json',
  },
});

export default instance;

Then, in your component:

import React from 'react';
import axiosConfig from './axiosConfig';

function MyComponent() {
  const fetchData = async () => {
    try {
      const response = await axiosConfig.get('/posts/1'); // Uses the configured baseURL
      console.log(response.data);
    } catch (error) {
      console.error(error);
    }
  };

  // ...
}

Interceptors

Axios interceptors allow you to intercept requests or responses before they are handled. This is useful for tasks like adding authentication headers or logging requests.

// interceptors.js
import axios from 'axios';

axios.interceptors.request.use(
  (config) => {
    // Add authentication token to every request
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

axios.interceptors.response.use(
  (response) => {
    return response;
  },
  (error) => {
    // Handle global error handling (e.g., redirect to error page)
    return Promise.reject(error);
  }
);

Import this file in your main application file (e.g., index.js) to apply the interceptors globally.

Best Practices

  • Error Handling: Always include proper error handling using try...catch blocks.
  • Loading States: Provide visual feedback to the user while data is being fetched (e.g., a loading spinner).
  • Data Validation: Validate the data received from the API to ensure it's in the expected format.
  • Security: Be mindful of security best practices when handling sensitive data. Never hardcode API keys or credentials directly into your code. Use environment variables.
  • Cancellation: For long-running requests, consider using Axios's