Usage of Axios in React Applications

Reading Time: 6 minutes

In this blog, we will see how to work with Axios in a React application to make GET, POST, PUT, and DELETE requests to perform CRUD actions. Axios is a popular, promise-based HTTP client that sports an easy-to-use API and can be used in both the browser and Node.js.

A very common task of a web client application is making HTTP requests to API and fetching data from APIs. We will be creating a very unique application that no one has probably never built and we could potentially sell this app and make millions. A To-do App.

Creating a React project

We first create a react app using create-react-app command.

create-react-app todo-app

Setting up Mock APIs

For this project, I have set up mock APIs and defined my custom request and response payload using mockapi.io so that we don’t have to rely on an actual backend server.

You can check out the finished project here and get a better idea about it. Todo App

React app using Axios

Adding Axios to project

As Axios is a third-party library, we will need to add to the project we created. In your terminal, go to the change directory into your project:

cd todo-app

Then run this command to add axios:

npm install axios

Next, you will need to import Axios into the file you want to use it in.

Making GET request

For our todo-app, we need to first load the todos which are already saved in our database. So, when our app will load we need to make a GET request to the API to get the list of todos.

import './App.css';
import TodoList from "./TodoList";
import React, {useEffect, useState} from "react";
import axios from "axios";

function App() {

const [todos, setTodos] = useState([])

useEffect(() => { axios.get('https://5fd080cc1f23740016631bc7.mockapi.io/todos')
            .then(res => {
                setTodos(res.data)
            })
}, [])

return (
        <div>
            <TodoList todos={todos} />
        </div>
    );
}

export default App;

So first, we import axios from axios. Now call GET method in useEffect with 0 dependencies which means it will be executed only once and after the app is loaded.

You can use axios.get(URL) with a URL from an API endpoint to get a promise which returns a response object. Inside the response object, there is data that holds the value we expected from the API. We use this data property value to set the state we created for todos.

You can also get other information about the request, such as the status code under res.status or more information inside of res.request.

Making POST request

In a todo-app user should be able to add a to-do item. For that, we will need to send a POST request to the API.

App.js

import './App.css';
import TodoList from "./TodoList";
import React, {useEffect, useState} from "react";
import AddTodo from "./AddTodo";
import axios from "axios";

function App() {

    const [todos, setTodos] = useState([])
    useEffect(() => {
     axios.get('https://5fd080cc1f23740016631bc7.mockapi.io/todos')
            .then(res => {
                setTodos(res.data)
            })
    }, [])

    const deleteTodo = (id) => {
        axios.post('https://5fd080cc1f23740016631bc7.mockapi.io/todos',{name: name})
            .then(res => {
                setTodos(prevState => [...prevState, res.data]);
            })
    }

    return (
        <div>
            <TodoList todos={todos} />
            <hr/>
            <AddTodo onAddTodo={(name) => addTodo(name)}/>
        </div>
    );
}

export default App;

AddTodo.js

import React, {useState} from 'react';

const AddTodo = (props) => {
    const [todoName, setTodoName] = useState('')

    return (
        <div style={{margin: '5px'}}>
            <input type='text' onChange={(event) => setTodoName(event.target.value)}/>
            <button onClick={() => props.onAddTodo(todoName)}>Add</button>
        </div>
    )
}

export default AddTodo

We first create the “AddTodo” component where we can input the title of the todo and when the ‘Add’ button is clicked it emits a custom event ‘onAddTodo’ with the value of the todo title and. The ‘addTodo(name)’ in App.js is bound to this event, where we call the axios.post() method.

Axios.post(URL, data) requires an endpoint URL where you need to send the request along with the data. The post request gives you a response object which contains information that we can use. Here in the data property of response, we get the added todo object value with its id, name, and status.

Making PUT request

To update the status of a to-do item we need to send a PUT request to the API.

TodoView.js

import React, {useState, useEffect} from 'react'
import classes from './TodoView.module.css';

const TodoView = (props) => {
    const [doneTodo, setDoneTodo] = useState(props.todo.done)

    useEffect(() => {
        setDoneTodo(props.todo.done)
    }, [props.todo.done])

    return (
        <div className={classes.todo}>
            <input checked={doneTodo} onChange={() => props.changeTodoStatus({...props.todo, done:!doneTodo})} type='checkbox' style={{marginRight: "5px"}}/>
            <span>{props.todo.name}</span>
            <button onClick={() => props.dltTodo(props.todo.id)} className={classes.deleteBtn}>Delete</button>
        </div>
    )
}

export default TodoView;

App.js
import './App.css';
import TodoList from "./TodoList";
import React, {useEffect, useState} from "react";
import AddTodo from "./AddTodo";
import axios from "axios";
import axiosInstance from "./axios/TodoAxiosInstance";

function App() {

    const [todos, setTodos] = useState([])
    useEffect(() => {
        axios.get('https://5fd080cc1f23740016631bc7.mockapi.io/todos')
            .then(res => {
                setTodos(res.data)
            })
    }, [])

    const deleteTodo = (id) => {
        axios.delete('https://5fd080cc1f23740016631bc7.mockapi.io/todos/' + id)
            .then(res => {
                const updatedTodos = todos.filter(todo => todo.id !== id)
                setTodos(updatedTodos);
            })
    }

    const addTodo = (name) => {
        axios.post('https://5fd080cc1f23740016631bc7.mockapi.io/todos',{name: name})
            .then(res => {
                setTodos(prevState => [...prevState, res.data]);
            })
    }

    const changeTodoStatus = (updatedState) => {
        axios.put('https://5fd080cc1f23740016631bc7.mockapi.io/todos/' + updatedState.id,
            {...updatedState})
            .then(res => {
                setTodos(prevState => prevState.map(todo => (todo.id === res.data.id ? {...todo, done: res.data.done} : todo)))
            })
    };

    return (
        <div>
            <TodoList
                todos={todos}
                onDltTodo={(id) => deleteTodo(id)}
                onTodoStatusChange = {(updatedState) => changeTodoStatus(updatedState)}
            />
            <hr/>
            <AddTodo onAddTodo={(name) => addTodo(name)}/>
        </div>
    );
}

export default App;

In the TodoView component, we emit a custom event when the checkbox value is changed and that is sent to the TodoList -> App through prop chaining. In-App component ‘changeTodoStatus’ method is bound to this custom event and here we execute the PUT request.

Axios.put(URL, data) is the same as the POST request. It requires an endpoint URL and data which needs to update. In return, we get a response-object that has the information we can use in our app.

Making DELETE request

To remove a to-do item we need to make a DELETE request.

App.js

const deleteTodo = (id) => {
        axios.delete('https://5fd080cc1f23740016631bc7.mockapi.io/todos/' + id)
            .then(res => {
                const updatedTodos = todos.filter(todo => todo.id !== id)
                setTodos(updatedTodos);
            })
    }

In the TodoView component when the ‘delete button’ is clicked we emit a custom event with the ‘id’ of the to-do. This ‘id’ is passed to App component through prop chaining from TodoView -> TodoList -> App. In App component we have deleteTodo, here we execute the axios.delete() method.

The axios.delete(URL) requires the URL of the endpoint. The mock API we have used here requires the ‘base URL + /todo-id’ to delete that todo. We get a response object in return containing information about the response which we can use.

Using Base Instance in Axios

In a Base Instance we can define base url and other default configurations. We can make multiple base instances. For example we also have APIs for Users and we can set base url and different configurations for that.

We create a file axios/todoAxiosInstance.js.

import axios from 'axios';

const axiosInstance = axios.create({
    baseURL: 'https://5fd080cc1f23740016631bc7.mockapi.io'
});

axiosInstance.defaults.headers.common['Content-Type'] = 'application/json';

Now we can use this axios instance instead of default axios. We will now no longer need to give the whole URL every time we create an axios method. We have also given headers which will be added in each request made using this axios instance.

import './App.css';
import TodoList from "./TodoList";
import React, {useEffect, useState} from "react";
import AddTodo from "./AddTodo";
import axiosInstance from "./axios/TodoAxiosInstance";

function App() {

    const [todos, setTodos] = useState([])
    useEffect(() => {
        axiosInstance.get('/todos')
            .then(res => {
                setTodos(res.data)
            })
    }, [])

    const deleteTodo = (id) => {
        axiosInstance.delete('/todos/' + id)
            .then(res => { ...
            })
    }

    const addTodo = (name) => {
        axiosInstance.post('/todos',{name: name})
            .then(res => {...
            })
    }

    const changeTodoStatus = (updatedState) => {
        axiosInstance.put('/todos/' + updatedState.id,
            {...updatedState})
            .then(res => {...
            })
    };

Making Interceptors

Interceptors allow you to step in before a request is sent or a response is received and execute the code you want or modify the request or response or handle errors.

TodoAxiosInstance.js

import axios from 'axios';

const axiosInstance = axios.create({
    baseURL: 'https://5fd080cc1f23740016631bc7.mockapi.io'
});

axiosInstance.defaults.headers.common['Content-Type'] = 'application/json';

axiosInstance.interceptors.response.use(response => {
    // code to be excuted.
    return response;
}, error => {
    ...
});

axiosInstance.interceptors.request.use(request => {
    // code to be executed
    return request;
}, error => {
    ...
});

export default axiosInstance;

Request/Response should always be returned.

Conclusion

In this tutorial, you explored several examples on how to use Axios inside a React application to create HTTP requests and handle responses.

You can learn more about Axios from the: https://github.com/axios/axios

You can check out the code here: Todo app code

Leave a Reply