DEV Community

Apollo Fredrick
Apollo Fredrick

Posted on

React API calls made simple with Axios

React is a JavaScript library for building user interfaces. Often you will want to fetch data from an API and display it in your React application.
Axios is a promise-based HTTP client that makes it easy to fetch data from APIs.
In this tutorial I will show you the simplest way to fetch API data and display it in your website.

Prerequisites

You should have a basic knowledge of React

Install Axios

Install Axios in your project folder using the following command:

npm install axios
Enter fullscreen mode Exit fullscreen mode

Import Axios

Import Axios in the component which you want to make API calls in as shown below:

import React, { useEffect, useState } from 'react';
import axios from 'axios';
Enter fullscreen mode Exit fullscreen mode

Making a GET Request

To make a GET request, use the following code:

axios.get(url)
  .then(response => {
    // Handle the successful response here
    console.log(response.data);
  })
  .catch(error => {
    // Handle errors here
    console.error('Error fetching data:', error);
  });
Enter fullscreen mode Exit fullscreen mode

Handling Asynchronous Operations

To handle asynchronous functions we use 'async/await' since API calls are asynchronous operations and React ensures that the UI remains responsive during these calls:

const fetchData = async() =>{
      try {
        const response = await axios.get(url)
        setData([response.data])
      } catch (error) {
        console.log(error)
      }
    }
    fetchData()
Enter fullscreen mode Exit fullscreen mode

Integrate with React Components

Integrate your knowledge of data fetching in your React components as shown below:

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

const App = () => {
  const [data, setData] = useState([])
  const url = "https://api.chucknorris.io/jokes/random"

  useEffect(() => {
    const fetchData = async() =>{
      try {
        const response = await axios.get(url)
        setData([response.data.value])
      } catch (error) {
        console.log(error)
      }
    }
    fetchData()
  }, [])
  return (
    <ul>
      {data.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
  </ul>
  )
}

export default App

Enter fullscreen mode Exit fullscreen mode

We use the useEffect hook to call the API when the component mounts.
Axios makes the Get request and returns a promise. When the promise resolves, we set the state using setData.
We finally use the map function to loop the data and display it on the page.
Remove React.StrictMode in your index.js file(If you are using Create-React-App) or main.js file(If you are using Vite) to prevent the useEfect hook from running twice.
Refresh the page to get more Chuck Norris jokes.

Top comments (1)

Collapse
 
marlo-bb profile image
ِMarlo Ber

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { FaTrashAlt } from "react-icons/fa";
import { Link } from 'react-router-dom';

export default function Home() {
const [characters, setCharacters] = useState([]);
const [name, setName] = useState('');
const [image, setImage] = useState('');
const [gender, setGender] = useState('');
const [search, setSearch] = useState('');
const [user, setUser] = useState(null);

const url = 'api url

``
';

useEffect(() => {
const userData = localStorage.getItem('user');
if (userData) {
setUser(JSON.parse(userData));
}
}, []);

const getData = () => {
axios.get(url)
.then(response => {
setCharacters(response.data);
})
.catch(err => {
console.error( err);
});
};

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

const submit = (e) => {
e.preventDefault();

if (!user) return;

const newCharacter = {
  name,
  image,
  gender,
  userId: user.id,
};

axios.post(url, newCharacter)
  .then(() => {
    getData(); 
    setName('');
    setImage('');
    setGender('');
  })
  .catch(error => {
    console.error( error);
  });
Enter fullscreen mode Exit fullscreen mode

};

const filteredCharacters = characters.filter(char =>
char.name.toLowerCase().includes(search.toLowerCase())
);

const deletePost = (id) => {
axios.delete(${url}/${id})
.then(() => {
getData();
})
.catch(err => {
console.error(err);
});
};

return (

  <div className="max-w-md mx-auto mb-6">
    <input
      type="text"
      placeholder="Search..."
      value={search}
      onChange={(e) => setSearch(e.target.value)}
      className="w-full h-10 p-3 mb-2 bg-white border-2 border-teal-900 rounded-2xl"
    />
  </div>

  {!user ? (
    <div className="max-w-sm mx-auto p-6 bg-gray-100 text-black mb-6 rounded shadow-inner text-center">
      <p className="font-semibold text-lg">Login Required</p>
      <p className="mt-2">You must log in to add characters.</p>
      <Link to="/login">
        <button className="mt-3 px-4 py-2 bg-green-900 text-white rounded hover:bg-green-600 transition">
          Login
        </button>
      </Link>
    </div>
  ) : (
    <div className="max-w-sm rounded-2xl bg-teal-900 mx-auto p-8 mb-6">
      <h2 className="text-xl font-bold mb-3 text-white">Add New Character</h2>
      <form onSubmit={submit}>
        <input
          type="text"
          placeholder="Name"
          value={name}
          onChange={(e) => setName(e.target.value)}
          className="w-full p-3 h-10 mb-2 bg-white border-2 border-teal-900 rounded-2xl"
          required
        />
        <input
          type="text"
          placeholder="Image URL"
          value={image}
          onChange={(e) => setImage(e.target.value)}
          className="w-full h-10 p-3 mb-2 bg-white border-2 border-teal-900 rounded-2xl"
          required
        />
        <select
          value={gender}
          onChange={(e) => setGender(e.target.value)}
          className="w-full p-1 h-10 mb-2 bg-white border-2 border-teal-900 rounded-2xl"
        >
          <option value="">Gender</option>
          <option value="male">Male</option>
          <option value="female">Female</option>
        </select>
        <button
          type="submit"
          className="w-full text-teal-900 py-2 rounded-2xl bg-white hover:bg-teal-600"
        >
          Add
        </button>
      </form>
    </div>
  )}

  <hr className="text-teal-900" />


  <div>
    <p className="text-3xl font-bold text-center py-5">All Characters</p>
    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 m-5">
      {filteredCharacters.length === 0 ? (
        <p className="text-center text-black w-full">Oops!</p>
      ) : (
        filteredCharacters.map((char) => (
          <div key={char.id} className="bg-white rounded-2xl shadow p-4">
            <div>
            <img
              src={char.image}
              alt={char.name}
              className="w-full h-full object-contain mx-auto rounded-2xl"
            />
            </div>
            <div className="flex justify-between p-2">
              <div>
                <h3 className="font-semibold text-2xl text-black mt-2">{char.name}</h3>
                <p className="text-sm text-gray-600">
                  {char.gender === 'male' ? 'Male' : 'Female'}
                </p>
              </div>
              {user && char.userId && char.userId === user.id && (
                <button
                  onClick={() => deletePost(char.id)}
                  className="hover:text-red-700"
                >
                  <FaTrashAlt className="text-red-600 h-6 w-6" />
                </button>
              )}
            </div>
          </div>
        ))
      )}
    </div>
  </div>
</div>

);
}