Data Fetching with `useEffect` in React JS

beginner
23 min

Data Fetching with useEffect in React JS

Welcome to our comprehensive guide on data fetching with useEffect in React JS! In this tutorial, we'll explore how to fetch and manage data in your React applications. By the end of this lesson, you'll have a solid understanding of useEffect, and you'll be able to apply these concepts to your own projects. šŸŽÆ

Introduction

useEffect is a React Hook that lets you perform side effects in your functional components. It's a powerful tool for fetching data, handling subscriptions, and more. In this lesson, we'll focus on using useEffect for data fetching.

Prerequisites

Before diving into data fetching, make sure you have a basic understanding of the following concepts:

Goals

By the end of this tutorial, you'll know how to:

  • Fetch data from an API
  • Manage the loading state
  • Handle errors
  • Update the component when data changes
  • Implement a cache for better performance

Setting up the project

Let's start by creating a new React project using Create React App:

bash
npx create-react-app data-fetching-demo cd data-fetching-demo

Project Structure

The project structure looks like this:

data-fetching-demo ā”œā”€ā”€ node_modules ā”œā”€ā”€ public ā”œā”€ā”€ src │ ā”œā”€ā”€ App.css │ ā”œā”€ā”€ App.js │ ā”œā”€ā”€ App.test.js │ ā”œā”€ā”€ index.css │ ā”œā”€ā”€ index.js │ └── logo.svg └── package.json

Starting the project

To start the project, run the following command in your terminal:

bash
npm start

Fetching Data with useEffect

Now let's dive into the main topic: fetching data with useEffect.

Creating a new component

First, we'll create a new component called PostList that will display a list of posts. We'll use useEffect to fetch the data and update the component when it changes.

Inside the src folder, create a new file called PostList.js:

bash
touch src/PostList.js

Replace its contents with the following code:

jsx
import React, { useState, useEffect } from 'react'; function PostList() { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { // Fetch data and manage loading state }, []); return ( <div> {loading && <p>Loading...</p>} {error && <p>Error: {error}</p>} {posts.map((post, index) => ( <div key={index}> <h2>{post.title}</h2> <p>{post.body}</p> </div> ))} </div> ); } export default PostList;

In this code, we've defined three state variables: posts, loading, and error. The useEffect hook is empty for now, but we'll fill it in soon.

Fetching data from an API

Now we'll use useEffect to fetch data from the JSONPlaceholder API. We'll make an API call to fetch a list of posts and update the component with the response.

Replace the contents of the useEffect hook in the PostList component with the following code:

jsx
useEffect(() => { const fetchPosts = async () => { try { const response = await fetch('https://jsonplaceholder.typicode.com/posts'); const data = await response.json(); setPosts(data); setLoading(false); } catch (error) { setError(error); setLoading(false); } }; fetchPosts(); }, []);

This code defines an asynchronous function called fetchPosts that fetches the data from the API and updates the component's state. It also handles errors by setting the error state variable.

Updating the App component

Now we'll update the App component to include the PostList component.

Replace the contents of the App.js file with the following code:

jsx
import React from 'react'; import './App.css'; import PostList from './PostList'; function App() { return ( <div className="App"> <PostList /> </div> ); } export default App;

With this change, the PostList component will be rendered inside the App component, and data will be fetched and displayed.

Running the project

To see the data fetching in action, run the following command in your terminal:

bash
npm start

You should now see the list of posts being displayed in your browser.

Bonus: Implementing a cache

To improve performance, we can implement a simple cache for the data. This way, we can avoid unnecessary API calls when the component is updated.

Update the useEffect hook in the PostList component with the following code:

jsx
useEffect(() => { let isMounted = true; const fetchPosts = async () => { try { const response = await fetch('https://jsonplaceholder.typicode.com/posts'); const data = await response.json(); if (isMounted) { setPosts(data); setLoading(false); } } catch (error) { setError(error); setLoading(false); } }; fetchPosts(); // Cleanup function return () => { isMounted = false; }; }, []);

This code adds a let isMounted = true variable that tracks whether the component is currently mounted. The fetchPosts function is updated to only set the data and update the loading state if isMounted is true.

The cleanup function is added at the end of the useEffect hook to set isMounted to false when the component unmounts.

Conclusion

You've now learned how to fetch data with useEffect in React JS! You can apply these concepts to fetch data from various APIs and update your components when the data changes.

Remember to handle errors gracefully and manage the loading state to provide a smooth user experience.

Quiz

šŸ“ Note: Answers can be found in the comments within the code.

Quick Quiz
Question 1 of 1

What does the `useEffect` hook do in React JS?

Quick Quiz
Question 1 of 1

What does the `let isMounted = true` variable do in the `useEffect` hook?

Quick Quiz
Question 1 of 1

What does the cleanup function do in the `useEffect` hook?