React + APIs, Part 1: Fetch posts with fetch

John John 3 min
React + APIs, Part 1: Fetch posts with fetch

Beginner-friendly guide to fetching JSON from JSONPlaceholder using fetch in a Vite + React app. Build loading and error states and render a posts list. Includes a handoff to Part 2 (Axios + custom hook).

React API Series: Part 1 - Fetching Data with Fetch

In modern web development, interacting with APIs is a crucial skill. APIs (Application Programming Interfaces) allow us to retrieve data from servers, enabling dynamic web applications. In this first part of our three-part series, we'll set up a basic application using React and the Vite build tool, fetching posts from the JSONPlaceholder API.

Glossary

  • API: A set of rules that allows one piece of software to interact with another.
  • Endpoint: A URL where an API can be accessed by a client to perform operations (like fetching data).
  • JSON: JavaScript Object Notation; a lightweight format for data interchange that is easy to read and write.

Project Setup

  1. Create a new Vite project by running the commands:

    npm create vite@latest react-api-series --template react
    cd react-api-series
    npm install
  2. Run the development server:

    npm run dev

    The server should now be running at http://localhost:5173.

Create src/api/client.js

First, let’s create a separate file to handle our API client. This will allow us to fetch posts using the Fetch API.

Creating client.js

// src/api/client.js

export async function getPosts() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts');
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error fetching posts:', error);
    throw error;
  }
}

What this code does

  • Defines an asynchronous function getPosts to fetch data from the specified endpoint.
  • Checks for network errors by examining the response status using response.ok.
  • Parses the response to JSON if the fetch was successful.
  • Catches and logs errors that may occur during the fetch operation, rethrowing them for upstream handling.

Create src/App.jsx

Next, let’s modify our main application component to utilize the getPosts function and display the list of posts.

Modifying App.jsx

// src/App.jsx
import React, { useEffect, useState } from 'react';
import { getPosts } from './api/client';

function App() {
  const [posts, setPosts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const postsData = await getPosts();
        setPosts(postsData);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    }
    fetchData();
  }, []);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      <h1>Posts</h1>
      <ul>
        {posts.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;

What this code does

  • Defines an App functional component, managing three states: posts, loading, and error.
  • Uses the useEffect hook to fetch posts once the component mounts.
  • Handles data fetching with an asynchronous function fetchData, updating state based on the fetch outcome.
  • Renders a loading message while loading, an error message if an error occurs, or the list of post titles if successful.

Recap

In part one, we spun up a Vite-powered React app, built a lightweight API client to pull posts from JSONPlaceholder, and handled loading and error states for a smooth, resilient UI.
Browse the code on GitHub: github repository

Part 2

In the next part, we will enhance our data fetching by implementing Axios and custom hooks for improved data management and reusability.

Part 2: Using Axios with Hooks !