Fetch data in useEffect and manage loading and error states with useState. Handle all three states: loading spinner, error message, and success content. TanStack Query or SWR are better for production apps.
Data Fetching Patterns
// Simple fetch with useEffect
function Posts() {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch("/api/posts")
.then(r => r.json())
.then(setPosts)
.catch(setError)
.finally(() => setLoading(false));
}, []);
if (loading) return ;
if (error) return ;
return {posts.map(p => - {p.title}
)}
;
}