Introduction
Loading states show users that data is being fetched. This helps avoid confusion and improves user experience.
Jump into concepts and practice - no test required
Loading states show users that data is being fetched. This helps avoid confusion and improves user experience.
import { useState, useEffect } from 'react'; function Component() { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { fetch('/api/data') .then(res => res.json()) .then(json => { setData(json); setLoading(false); }); }, []); if (loading) return <p>Loading...</p>; return <div>{JSON.stringify(data)}</div>; }
Use a loading state variable to track if data is still loading.
Show a simple message or spinner while loading is true.
const [loading, setLoading] = useState(true); if (loading) { return <p>Loading data, please wait...</p>; }
useEffect(() => {
fetch('/api/items')
.then(res => res.json())
.then(data => {
setItems(data);
setLoading(false);
});
}, []);if (loading) { return <div role="status" aria-live="polite">Loading...</div>; }
This component fetches a list of users from an API. While waiting, it shows "Loading users...". When data arrives, it shows the user names in a list.
import { useState, useEffect } from 'react'; export default function UserList() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { async function fetchUsers() { const res = await fetch('https://jsonplaceholder.typicode.com/users'); const data = await res.json(); setUsers(data); setLoading(false); } fetchUsers(); }, []); if (loading) { return <p>Loading users...</p>; } return ( <ul> {users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ); }
Always provide feedback to users when waiting for data.
Use semantic HTML and ARIA roles for accessibility.
Keep loading messages short and clear.
Loading states tell users data is coming.
Use a state variable to track loading.
Show a message or spinner while loading.
import { useState, useEffect } from 'react';
export default function DataLoader() {
const [loading, setLoading] = useState(true);
const [data, setData] = useState(null);
useEffect(() => {
setTimeout(() => {
setData('Hello World');
setLoading(false);
}, 1000);
}, []);
if (loading) return <div>Loading...</div>;
return <div>{data}</div>;
}import { useState, useEffect } from 'react';
export default function Fetcher() {
const [loading, setLoading] = useState(false);
const [data, setData] = useState(null);
useEffect(() => {
setLoading(true);
fetch('/api/data')
.then(res => res.json())
.then(json => {
setData(json);
setLoading(false);
});
}, []);
if (loading) return <div>Loading...</div>;
return <div>{JSON.stringify(data)}</div>;
}