How to Use Fetch API in React: Simple Guide with Examples
In React, use the
fetch API inside a useEffect hook to load data when the component mounts. Handle the response with async/await and update state with useState to show the fetched data.Syntax
The fetch API is used to request data from a URL. It returns a promise that resolves to a response object. You usually call response.json() to get the data as JSON.
In React, you place fetch inside useEffect to run it once when the component loads. Use useState to store the data and trigger a re-render.
javascript
import React, { useState, useEffect } from 'react'; function MyComponent() { const [data, setData] = useState(null); useEffect(() => { fetch('https://api.example.com/data') .then(response => response.json()) .then(json => setData(json)); }, []); return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>; }
Output
<div>Loading... (then JSON data appears)</div>
Example
This example fetches a list of users from a public API when the component loads. It shows "Loading..." while waiting, then displays the user names.
javascript
import React, { useState, useEffect } from 'react'; export default function UserList() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { async function fetchUsers() { try { const response = await fetch('https://jsonplaceholder.typicode.com/users'); const data = await response.json(); setUsers(data); } catch (error) { console.error('Error fetching users:', error); } finally { setLoading(false); } } fetchUsers(); }, []); if (loading) return <p>Loading users...</p>; return ( <ul> {users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ); }
Output
<ul><li>Leanne Graham</li><li>Ervin Howell</li><li>Clementine Bauch</li>... (and more users)</ul>
Common Pitfalls
- Not using
useEffectcauses fetch to run on every render, leading to infinite loops. - Forgetting to handle errors can crash your app or leave it stuck loading.
- Not updating state properly means UI won't show new data.
- Not cleaning up or cancelling fetch requests can cause warnings if the component unmounts early.
javascript
import React, { useState, useEffect } from 'react'; // Wrong: fetch runs every render causing infinite loop function Wrong() { const [data, setData] = useState(null); fetch('https://api.example.com/data') .then(res => res.json()) .then(json => setData(json)); return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>; } // Right: fetch inside useEffect with empty dependency array function Right() { const [data, setData] = useState(null); useEffect(() => { fetch('https://api.example.com/data') .then(res => res.json()) .then(json => setData(json)); }, []); return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>; }
Quick Reference
Tips for using fetch in React:
- Always use
useEffectto run fetch once on mount. - Use
async/awaitinsideuseEffectfor cleaner code. - Handle errors with
try/catchor.catch(). - Show loading state to improve user experience.
- Clean up if needed when component unmounts.
Key Takeaways
Use fetch inside useEffect with an empty dependency array to load data once.
Store fetched data in state with useState to update the UI.
Handle loading and error states to keep the app stable and user-friendly.
Avoid running fetch on every render to prevent infinite loops.
Use async/await syntax inside useEffect for clearer asynchronous code.