Different Ways to Fetch Data in React

Drawing of me
Alan Yang5 min read

In this article, I will be explaining different ways to fetch data in React. I will be using the Random User Generator as an API endpoint and I will also provide a CodeSandbox for each example.

Table of Contents

Fetch API

The Fetch API is an API that is available in most modern browsers. It only takes in one mandatory parameter, the path to the resource you want to fetch, and it returns a Promise that resolves to a Response.

fetch
import { StrictMode, useState, useEffect } from "react";
import ReactDOM from "react-dom";

export default function App() {
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch("https://randomuser.me/api")
      .then((response) => response.json())
      .then((data) => setData(data))
      .catch((err) => {
        const errorMessage = "Error: " + err.message;
        setError(errorMessage);
        console.log(errorMessage);
      })
      .finally(() => setIsLoading(false));
  }, []);

  if (isLoading) return "Loading...";
  if (error) return error;

  return (
    <div className="App">
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  rootElement
);

View Fetch API example on CodeSandbox

Axios

Axios is a Promise-based HTTP client for the browser and Node.js. It is an isomorphic client, which means it works server-side as well as client-side. On the server, Axios uses the Node.js HTTP module. On the client, Axios uses the XMLHttpRequest object.

axios
import axios from "axios";
import { StrictMode, useState, useEffect } from "react";
import ReactDOM from "react-dom";

export default function App() {
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);

  useEffect(() => {
    axios
      .get("https://randomuser.me/api")
      .then((response) => setData(response.data))
      .catch((err) => {
        const errorMessage = "Error: " + err.message;
        setError(errorMessage);
        console.log(errorMessage);
      })
      .finally(() => setIsLoading(false));
  }, []);

  if (isLoading) return "Loading...";
  if (error) return error;

  return (
    <div className="App">
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  rootElement
);

View Axios example on CodeSandbox

Async/Await

Async/await functions are a new feature of ES2017 that allow us to write asynchronous code in a much more readable and declarative way. Async functions always return a Promise and other values are wrapped in a resolved Promise automatically. Await makes our code wait for a Promise to resolve before continuing.

Async/Await with Fetch API

Using async/await with Fetch API.

async/await-fetch
import { StrictMode, useState, useEffect } from "react";
import ReactDOM from "react-dom";

export default function App() {
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);

  async function fetchData() {
    try {
      const response = await fetch("https://randomuser.me/api");
      const data = await response.json();
      setData(data);
    } catch (err) {
      const errorMessage = "Error: " + err.message;
      setError(errorMessage);
      console.log(errorMessage);
    } finally {
      setIsLoading(false);
    }
  }

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

  if (isLoading) return "Loading...";
  if (error) return error;

  return (
    <div className="App">
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  rootElement
);

View Async/Await Fetch API example on CodeSandbox

Async/Await with Axios

Using async/await with Axios is similar to using async/await with Fetch API.

async/await-axios
import axios from "axios";
import { StrictMode, useState, useEffect } from "react";
import ReactDOM from "react-dom";

export default function App() {
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);

  async function fetchData() {
    try {
      const response = await axios.get("https://randomuser.me/api");
      setData(response.data);
    } catch (err) {
      const errorMessage = "Error: " + err.message;
      setError(errorMessage);
      console.log(errorMessage);
    } finally {
      setIsLoading(false);
    }
  }

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

  if (isLoading) return "Loading...";
  if (error) return error;

  return (
    <div className="App">
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  rootElement
);

View Async/Await Axios example on CodeSandbox

SWR

SWR is a React Hooks library for data fetching developed by Vercel. SWR first returns the data from cache (stale), then sends the fetch request (revalidate), and finally comes with the up-to-date data again.

swr
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import useSWR from "swr";

async function fetcher(...args) {
  const res = await fetch(...args);
  return res.json();
}

export default function App() {
  const { data, error } = useSWR("https://randomuser.me/api", fetcher);

  if (!data && !error) return "Loading...";
  if (error) return "Error: " + error.message;

  return (
    <div className="App">
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  rootElement
);

View SWR example on CodeSandbox

React Query

React Query is a React Hooks library for data fetching developed by TanStack. React Query tries to solve the problem of managing server state and caching data in a declarative way.

react-query
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { QueryClient, QueryClientProvider, useQuery } from "react-query";

const queryClient = new QueryClient();

function FetchUser() {
  const { isLoading, error, data } = useQuery("userData", () =>
    fetch("https://randomuser.me/api").then((response) => response.json())
  );

  if (isLoading) return "Loading...";
  if (error) return "Error: " + error.message;

  return (
    <div className="App">
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <FetchUser />
    </QueryClientProvider>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  rootElement
);

View React Query example on CodeSandbox