When building a React app with Vite and a REST API, you quickly need to fetch data. You face a choice between using the browser's built-in fetch function or installing a popular data-fetching library like TanStack React Query.
- How native fetch handles basic API calls in React.
- Why a dedicated data-fetching library like React Query exists.
- The hidden costs of managing loading and error states manually.
- A clear, definitive recommendation for your next project.
Using Native Fetch with React and Vite
Native fetch is built right into the browser, meaning zero extra downloads for your users. You manage data by combining fetch with React's useState and useEffect hooks.
import { useState, useEffect } from 'react';
function UserProfile() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('https://api.example.com/user')
.then(res => res.json())
.then(data => {
setUser(data);
setLoading(false);
});
}, []);
if (loading) return <p>Loading...</p>;
return <div>{user.name}</div>;
}
This approach works fine for small apps, but it requires you to write a lot of boilerplate code for every single endpoint.
Using React Query for Automated Caching
React Query is a third-party library that handles caching, background updates, and request deduplication out of the box. Caching means storing fetched data in memory so your app doesn't download the same information twice.
import { useQuery } from '@tanstack/react-query';
function UserProfile() {
const { data, isLoading } = useQuery({
queryKey: ['user'],
queryFn: () => fetch('https://api.example.com/user').then(res => res.json())
});
if (isLoading) return <p>Loading...</p>;
return <div>{data.name}</div>;
}
React Query cuts out dozens of lines of state management code and automatically keeps your UI fresh when users switch browser tabs.
Common mistakes to watch out for
A frequent mistake with native fetch is forgetting to handle race conditions when components unmount quickly. Developers also often skip implementing request error handling, which leads to blank screens when the server fails.
When using React Query, developers sometimes overcomplicate things by putting every single piece of local UI state into the global cache. Remember that React Query is strictly for server data, not for things like whether a modal is open.
The final verdict
Use native fetch if you are building a tiny portfolio site or a simple prototype with fewer than three API calls. For any real-world production app with multiple screens and user interactions, install React Query immediately. Open your terminal right now, run npm install @tanstack/react-query, and save yourself hours of writing manual caching logic.