reactjs
/

React API Calls – Fetching & Managing Remote Data

Last Sync: Today

On this page

4
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

reactjs

React API Calls – Fetching & Managing Remote Data

Data Fetching in React

In modern web apps, components often need to display data from a server. In React, API calls are considered 'side effects' because they interact with the outside world. These are typically handled inside the useEffect hook to ensure they run at the correct point in the component lifecycle.

The Fetch API vs. Axios

You have two primary choices for making HTTP requests: the native browser fetch() API or the popular third-party library Axios.

FeatureFetch APIAxios
InstallationBuilt-in (No install)Requires `npm install axios`
JSON ParsingManual (`res.json()`)Automatic
Error HandlingManual (check `res.ok`)Automatic for 4xx/5xx status
InterceptorsNoYes (Great for Auth tokens)
Timeout SupportManual (AbortController)Simple config property

Handling Loading & Error States

A professional API implementation must handle three distinct states: Loading (the request is in flight), Error (the request failed), and Data (the request succeeded).

React JSXRead-only
1
import { useState, useEffect } from 'react';

function UserList() {
  const [users, setUsers] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchUsers = async () => {
      try {
        const response = await fetch('https://jsonplaceholder.typicode.com/users');
        if (!response.ok) throw new Error('Failed to fetch data');
        const data = await response.json();
        setUsers(data);
      } catch (err) {
        setError(err.message);
      } finally {
        setIsLoading(false);
      }
    };

    fetchUsers();
  }, []);

  if (isLoading) return <p>Loading users...</p>;
  if (error) return <p style={{ color: 'red' }}>Error: {error}</p>;

  return (
    <ul>
      {users.map(user => <li key={user.id}>{user.name}</li>)}
    </ul>
  );
}

Best Practices

  • Cleanup after yourself: Use an AbortController to cancel requests if the component unmounts before the request finishes.
  • Abstract your API logic: Move fetch calls to a separate services/ folder to keep components clean.
  • Avoid 'Waterfall' fetches: If two API calls don't depend on each other, use Promise.all() to fetch them in parallel.
  • Consider a library: For complex apps, use TanStack Query (React Query) to handle caching, re-fetching, and background updates automatically.

Try it yourself

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

export default function GitHubProfile() {
  const [profile, setProfile] = useState(null);
  const [loading, setLoading] = useState(false);

  const fetchProfile = async (username) => {
    setLoading(true);
    try {
      const res = await fetch(`https://api.github.com/users/${username}`);
      const data = await res.json();
      setProfile(data);
    } catch (err) {
      alert('Error fetching user');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ padding: '20px' }}>
      <h3>GitHub User Finder</h3>
      <button onClick={() => fetchProfile('kishorekumar-s')}>
        Load My Profile
      </button>
      
      {loading && <p>Searching...</p>}
      
      {profile && (
        <div style={{ marginTop: '20px' }}>
          <img src={profile.avatar_url} width="100" style={{ borderRadius: '50%' }} />
          <h4>{profile.name || profile.login}</h4>
          <p>{profile.bio}</p>
          <p>Public Repos: {profile.public_repos}</p>
        </div>
      )}
    </div>
  );
}

Test Your Knowledge

Q1
of 3

Which hook is most appropriate for initiating an API call on component load?

A
useState
B
useMemo
C
useEffect
D
useCallback
Q2
of 3

What happens if you forget to add an empty dependency array [] to a fetch useEffect?

A
The code won't compile
B
The API call runs only once
C
The API call runs on every single render (Infinite loop potential)
D
The browser will block the request
Q3
of 3

What is the main benefit of using Axios over the native Fetch API?

A
It is 10x faster
B
It works without JavaScript
C
It automatically transforms JSON data and handles errors more gracefully
D
It is made by the React team

Frequently Asked Questions

Why do I see my API call running twice?

This usually happens in React Strict Mode during development. React intentionally mounts, unmounts, and re-mounts components to help you find side-effect bugs.

How do I send a POST request with Fetch?

Pass an options object as the second argument to fetch with method: 'POST', headers, and body: JSON.stringify(data).

What is an Interceptor in Axios?

It's a function that runs before a request is sent (e.g., to add an Auth token) or after a response is received (e.g., to handle 401 errors globally).

Previous

react dynamic routing

Next

react async handling

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.