Master the fetch API in React to retrieve external data. Learn to perform asynchronous requests and store JSON responses in your component state effectively.
Previously in this course, we covered introduction-to-side-effects-managing-external-logic-in-react and mastering-useeffect-dependencies-control-your-react-lifecycle. Those lessons established that a side effect is any operation that reaches outside of React's render cycle, such as talking to a server.
In this lesson, we will move from static data to real-world connectivity. You will learn to use the fetch API to retrieve movie data from a remote server, handle the asynchronous nature of network requests, and update your UI by saving that data into component state.
When you request data from an API, your JavaScript code doesn't stop and wait for the server to reply. If it did, your entire browser would "freeze" until the data arrived. Instead, network requests are asynchronous—the browser sends the request, continues executing other code, and handles the response later when it arrives.
In React, we manage this lifecycle by triggering the request in a useEffect hook and storing the result in useState.
To fetch data, we use the browser's native fetch() function. This function returns a Promise. We use the async/await syntax to handle the response cleanly, turning the raw stream of bytes from the server into usable JSON data.
Here is how we integrate this into our movie-browser project.
In your MovieBrowser.jsx component, we will initialize an empty array in state and fetch data as soon as the component mounts:
JSXimport { useState, useEffect } from CE9178">'react'; function MovieBrowser() { const [movies, setMovies] = useState([]); useEffect(() => { // Define an async function to handle the request async function fetchData() { try { const response = await fetch(CE9178">'https://api.example.com/movies'); const data = await response.json(); setMovies(data); } catch (error) { console.error("Failed to fetch movies:", error); } } fetchData(); }, []); // Empty array ensures this runs only once on mount return ( <ul> {movies.map(movie => ( <li key={movie.id}>{movie.title}</li> ))} </ul> ); }
useState([]): We initialize our state as an empty array because we expect a collection of movies.useEffect with []: By passing an empty dependency array, we tell React to run this effect exactly once: when the component first appears on the screen.async/await: The fetch function returns a promise. await pauses the function execution until the promise resolves.response.json(): The response object represents the HTTP response. We call .json() to parse the body into a JavaScript object.While this looks straightforward, understanding how to manage fetch-priority-api-optimize-resource-prioritization-for-core-web-vitals can help you further optimize how these requests are handled in high-traffic applications.
Modify your MovieBrowser component to fetch data from a placeholder API. You can use https://jsonplaceholder.typicode.com/posts (or a similar public JSON endpoint) if you don't have your own movie API ready yet.
items.useEffect to fetch the data from the URL..map() just like we learned in rendering-lists-of-data-in-react-a-practical-guide.[] in useEffect, the effect will run after every render. This leads to an infinite loop: the component renders, the effect updates the state, the state change triggers a re-render, and the cycle repeats.[]). Your component must be able to render without crashing if the data hasn't arrived yet.fetch call only rejects if the request itself fails (like a network timeout). If the server returns a 404 or 500 error, fetch will not throw an error. You must check response.ok before calling .json().Fetching data is the bridge between your UI and the outside world. By using useEffect with an empty dependency array, you ensure your data is requested only once upon mounting. By using async/await, you handle the asynchronous nature of the web gracefully, allowing you to update your state and re-render your components as soon as the data is ready.
Up next: We will address the "flicker" of empty screens by learning how to handle loading states while our data is in flight.
Learn how to use the map method for list rendering in React. Master the key prop to keep your dynamic movie lists efficient, performant, and bug-free.
Fetching Data from an API
Prop Drilling and Context API
Polishing the UI
Finalizing the Movie Browser
Review of Component Lifecycle
Review of State Management
Building a Modal Component
Introduction to PropTypes
Performance Optimization Basics
Handling Browser History
Working with LocalStorage
Building a Favorites List
Handling Media in React
Introduction to Testing
Debugging React Apps
Deployment Basics
Using External Libraries
Advanced