React Axios for HTTP method with REST API

In this tutorial, we’ll learn how to use React Axios with REST API operation. Axios is a simple promise-based HTTP client for the browser and node.js. Axios provides a simple to use a library in a small package with a very extensible interface.

In this tutorial, we’ll learn what is Axios library, and how to use it with the HTTP method. We’ll demonstrate an example of Axios with different HTTP methods and query params with request.

What is the purpose of React Axios library?

React is one of the most popular front-end frameworks, we need to access data from a remote source that can be rendered into a component. To communicate with the remote servers we have different API interfaces like REST API, GraphQL API, and more. They set a ruleset that defines best practices for sharing data between clients and the server.

The REST API is one of the most popular, we can consume REST API in React apps with a different approach and some of the most popular are.

  1. fetch API: In-built browser fetch API.
  2. Axios: Promise based HTTP client for the browser and node.js

There are many other libraries for making HTTP client request. Axios is promise-based, which gives us the ability to take advantage of JavaScript’s async and await for more readable asynchronous code. Here are the following advantages of Axios as follows.

  1. Make XMLHttpRequests from the browser
  2. Make http requests from node.js
  3. Supports the Promise API
  4. Intercept request and response
  5. Transform request and response data
  6. Cancel requests
  7. Automatic transforms for JSON data
  8. Client-side support for protecting against XSRF

React Axios example

Now let’s demonstrate how to use Axios react, we have articles on how to use fetch HTTP requests in one of our previous examples.

React Axios basic example

Let’s demonstrate a simple example of Axios with get a request to display a list of posts from https://jsonplaceholder.typicode.com/posts

We have to follow the below step to configure our React Axios example.

Step1: Create react app to demonstrate Axios react example

npx create-react-app axios-example
cd axios-example

Step 2: Install Axios library

npm install axios --save
Axios react example

Here is the screenshot of our react Axios basic example. We need to import Axios from the Axios. Let edit the app.js file to retrieve post data through Axios get method.

import { useEffect, useState } from "react";
import axios from "axios";

function App() {
  const [posts, setPosts] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const getPosts = async () => {
      const response = await axios.get(
        "https://jsonplaceholder.typicode.com/posts"
      );

      setPosts(response.data);
      setIsLoading(false);
    };

    getPosts();
  }, [posts]);

  return isLoading ? (
    <h1>Loading ...</h1>
  ) : (
    <div className='container'>
      <table className='table table-striped'>
        <thead>
          <tr>
            <th scope='col'>#</th>
            <th scope='col'>Title</th>
            <th scope='col'>Description</th>
          </tr>
        </thead>
        <tbody>
          { posts.map((post, index) => (
            <tr key={post.id}>
              <th scope='row'>{index + 1}</th>
              <td>{post.title}</td>
              <td>
                {post.body}
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

export default App;

We set the posts data we received as a component state from jsonplaceholder.typicode.com, so we can access it inside the render method. The posts variable is an array of objects, we loop through the posts using the map.


React Axios example with POST, PUT, DELETE method

In this tutorial, we will be focusing on CRUD operation using Axios with React context system. Let’s first create react apps, install Axios and create 2 more components. The Todos component displays a list of todo and Todo components to add new todo or edit existing todo.

Here is a screenshot of our React Axios with Context API

react axios example

Let’s demonstrate the second example of React axios CRUD operation, we used a JSON server to make an API call. Let’s first install JSON Server, it is up to you whether you want to install locally or global, I added as global. Here is how to install it in our system.

json-server -gobal install

All the HTTP requests to JSON Server are the same as Node-based express-js.

Step 1: Create Dummy data for HTTP Request

First, we need to create our React app, then create dummy data todos.json in your root project folder and add the following data.

{
  "todos": [
    {
      "task": "Meditation at 7 am",
      "status": "Completed",
      "id": "1"
    },
    {
      "task": "Breakfast at  8:00 am",
      "status": "Completed",
      "id": "2"
    },
    {
      "task": "Reading book 9-10:00 am",
      "status": "Pending",
      "id": "3"
    }
  ]
}

To request or access dummy data, we need to run our fake server using the following command in our project folder on the terminal.

 npx json-server --watch todos.json --port 3001

Now we can access our JSON data in URL on port number 3001

react axios post example

Step 2: Create API file

Let’s create a folder called src/api/someAPI.js, the someAPI you can give your server name like youtube.js or a name of your choice. Add the following code to it.

import axios from 'axios';

export default axios.create({
    baseURL: "http://localhost:3001",
})

Creating this file will allow us to reduce code, we don’t have to type the whole URL request for each Axios request method.

Step 3: Create Context for HTTP request

Let’s create a context folder and here we create our TodoContext.js, in this file we are managing our todos data, and performing CRUD operations on it. Let’s add code for our context in src/context/TodoContext.js

import { createContext, useState, useEffect } from "react";
import someAPI from "../api/someAPI";

const TodoContext = createContext();

export const TodoProvider = ({ children }) => {
  const [todos, setTodos] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [todoEdit, setTodoEdit] = useState({ todo: {}, isEdit: false });

  useEffect(() => {
    fetchTodos();
  }, []);

  // react axios get method
  const fetchTodos = async () => {
    const response = await someAPI.get('/todos');
    setTodos(response.data);
    setIsLoading(false);
  };

  // react axios post method
  const addTodo = async (newTodo) => {
    const response = await someAPI.post('/todos', newTodo);
    const data = response.data;
    debugger

    setTodos([data, ...todos]);
  };

   // react axios put method
  const updateTodo = async (id, todo) => {
    const response = await someAPI.put(`/todos/${id}`, todo);
    const data = response.data;
    debugger

    setTodos(
      todos.map((todo) => (todo.id === id ? { ...todo, ...data } : todo))
    );
  };

  // react axios delete method
  const deleteTodo = async (id) => {
    await someAPI.delete(`/todos/${id}`);
    setTodos(todos.filter((todo) => todo.id !== id));
  };

  const editTodoFnc = (todo) => {
    setTodoEdit({ todo, isEdit: true });
  };

  return (
    <TodoContext.Provider
      value={{
        todos,
        isLoading,
        todoEdit,
        addTodo,
        updateTodo,
        deleteTodo,
        editTodoFnc,
      }}
    >
      {children}
    </TodoContext.Provider>
  );
};

export default TodoContext;
    

In our context file, we have 3 data, todos are a list of all todo, isLoading, and todoEdit for setting edit mode with todo data to modify. We need to pass all our CRUD functions and data inside Provider component value props.

Step 4: Create components and wrapped them with TodoContext

In our App.js is the parent component to all other components, let’s create two components, we have Todos and Todo component. In our App.js we need to import TodoProvider, Todo, and Todos components.

import { TodoProvider } from "./context/TodoContext";
import Todo from "./components/todo/Todo";
import Todos from "./components/todos/Todos";
import "./App.css";

function App() {
  return (
    <TodoProvider>
      <div className="container">
        <h2>Context state management</h2>
        <div className="row">
          <div className="col-8"><Todos /></div>
          <div className="col-4"><Todo /></div>
        </div>
      </div>
    </TodoProvider>
  );
}

export default App;

Wrapping Todo and Todos with TodoProvider make underneath component can access data and method from TodoContext.

Step 5 React context hooks to access Context data and function

In our Todos.jsx we can now use react context hooks, the useContext to access data and function from the context. In our Todos component, we have to fetch todos and delete functions from the TodoContext by using the useContext. We are performing delete on the todo and adding the following code in the src/components/todos/Todos.jsx

import { useContext } from 'react';
import TodoContext from '../../context/TodoContext';
import './todos.css';

const Todos = () => {
  const { todos, isLoading, deleteTodo, editTodoFnc } = useContext(TodoContext);

  const handleDelete = (id) => {
    if (window.confirm('Are you sure want to delete')) {
      deleteTodo(id);
    }
  }
  if (!isLoading && !todos && todos.length === 0) {
    return <p>No todos yet!</p>;
  }
  return isLoading ? (
    <h1>Loading ...</h1>
  ) : (
    <div className='container'>
      <table className='table table-striped'>
        <thead>
          <tr>
            <th scope='col'>#</th>
            <th scope='col'>Task</th>
            <th scope='col'>Status</th>
            <th scope='col'>Edit</th>
            <th scope='col'>Delete</th>
          </tr>
        </thead>
        <tbody>
          { todos.map((todo, index) => (
            <tr key={todo.id}>
              <th scope='row'>{index + 1}</th>
              <td>{todo.task}</td>
              <td>
                <span>
                  {todo.status === 'Completed' ? 'Completed' : 'Pending'}
                </span>
              </td>
              <td>
                <button type='button' className='btn btn-primary' onClick={() => editTodoFnc(todo)}>
                  Edit
                </button>
              </td>
              <td>
                <button type='button' className='btn btn-danger' onClick={() => handleDelete(todo.id)}>
                  Danger
                </button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

export default Todos;

Step 6 Context API to perform React Axios POST and PUT

In the Todo.js we use the useContext function to access addTodo, updateTodo functions, and the editTodo data. In the Todo component, we are performing adding new Todo and editing existing Todo. We can use the editTodo to check if is an edit or new Todo operation by accessing editTodo.isEdit true or null.

Let’s add the following code in the src/todo/Todo.jsx

import { useContext, useEffect, useState } from 'react';
import TodoContext from '../../context/TodoContext';
import './todo.css';

const Todo = () => {
  const [task, setTask] = useState('');
  const [status, setStatus] = useState('');
  const { todoEdit, addTodo, updateTodo } = useContext(TodoContext);

  useEffect(() => {
    if (todoEdit.isEdit) { // check edit or new todo mode
      setTask(todoEdit.todo.task);
      setStatus(todoEdit.todo.status);
    }
  }, [todoEdit]);

  const handleInputChange = (e) => {
    e.target.name === 'task'
      ? setTask(e.target.value)
      : setStatus(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    if (task.length < 5) {
      alert('Task name should be minimum 5 character');
      return;
    }
    const todo = { task, status };
    if (todoEdit.isEdit) {
      updateTodo(todoEdit.todo.id, todo);
    } else {
      addTodo(todo);
    }
  };
  return (
    <div className='form-container'>
      <h3>Todo Form</h3>
      <form onSubmit={handleSubmit}>
        <div className='form-group'>
          <label>Task Name</label>
          <input
            className='form-control'
            id='taskId'
            placeholder='Task'
            onChange={handleInputChange}
            name='task'
            value={task}
          />
        </div>
        <div className='form-group mt-3 mb-4'>
          <label>Task Status</label>
          <div className='form-check'>
            <input
              className='form-check-input'
              type='radio'
              name='status'
              value='Pending'
              checked = {status === 'Pending' ? true : false }
              onChange={handleInputChange}
            />
            <label className='form-check-label'>Pending</label>
          </div>
          <div className='form-check'>
            <input
              className='form-check-input'
              type='radio'
              name='status'
              value='Completed'
              checked = {status === 'Completed' ? true : false }
              onChange={handleInputChange}
            />
            <label className='form-check-label'>Completed</label>
          </div>
        </div>

        <button type='submit' className='btn btn-primary'>
          Submit
        </button>
      </form>
    </div>
  );
};

export default Todo;

Error handling in Axios with async-await

Handling errors in Javascript promise with async-await is easy, we can use the try and catch statement as follows.

  const fetchTodos = async () => {
    try {
      const response = await someAPI.get("/todos");
      setTodos(response.data);
      setIsLoading(false);
    } catch (err) {
      console.log(err.message);
    }
  };

Axios React request with params and headers

In this section, we’ll demonstrate a few abstract examples where we can pass params in our react Axios params. Here is a simple example of the React Axios params query.

const axios = require('axios');

// Equivalent to axios.get('https://somedomain.com/search?category=electronic')
const res = await axios.get('https://somedomain.com/search', 
{ params: { category: 'electronic' }
});

The second example is Axios with a header with token Authorization and searches param query.

import axios from 'axios';

const SOMESERVER_URL = process.env.REACT_APP_SOMESERVER_URL;
const SOMESERVER_TOKEN = process.env.REACT_APP_TOKEN;

const somesite = axios.create({
   baseURL: SOMESERVER_URL,
   headers: { Authorization: token ${SOMESERVER_TOKEN}});


....
// searchTerm is user query
const params = new URLSearchParams({
   q: searchTerm
});

try {

      const response = await somesite.get(`/search/categories/${params}`);
     return response.data;
} catch (err) {
  // some error handling
}

// No need to call json() for Axios

Axios with context API, we can pass params as follows. First, we need to create API with Axios create. To access the following search URL.

https://www.somedomain.com/search?part=snippet&type=video&maxResults=5&key=.....&q=
import axios from "axios";

const KEY = ".....API KEY ......";

export default axios.create({
  baseURL: "https://www.somedomain.com/",
  params: {
    part: "snippet",
    type: "video",
    maxResults: 5,
    key: KEY,
  },
});

  ....
const search = async (searchTerm) => {
  const response = await someadomainName.get("/search", {
    params: {
      q: searchTerm,
    },
  });

    ....
  };

To add a limit number of response data we can use limit inside params.

export default axios.create({
    baseURL: 'https://someaAPI',
    params: {
        _limit: 10
    }
});

Conclusion: We learned how to use Axios simple promise-based client to make HTTP requests. We demonstrated a few examples of how to use Axios in React application. The Axios is one of the most used and popular libraries for making HTTP requests.

Related Post

  1. When and how to use React Context API?
  2. React router navigate outside component.
  3. How to implement React routing using react-router-dom?

Spread the love

Leave a Comment

Your email address will not be published.

Scroll to Top