Data Fetching & Caching
Why fetching data inside useEffect is a bad idea, and how modern caching libraries (like React Query or SWR) solve it.
The useEffect Trap
In the past, fetching data in React involved a standard boilerplate: setting up three state variables (data, isLoading, error), writing a useEffect, calling fetch(), and manually updating those state variables.
This approach is now considered an anti-pattern for production apps. It causes a 'waterfall' of loading spinners, it doesn't cache data (if you leave the page and come back, you see a spinner again), and it doesn't deduplicate requests (if two components need the same data, you fetch it twice).
Enter Caching Libraries
Modern React uses libraries like **TanStack Query (React Query)** or **SWR**.
Instead of manually managing state, you provide a 'Query Key' (like ['users']) and an async function. The library handles the rest.
If you ask for ['users'] in five different components, the library merges them into a *single* network request and shares the cached result with all five.
How it works under the hood
These libraries maintain a global cache outside of the React component tree.
When a component mounts, it subscribes to a specific cache key.
If the data is in the cache, it is returned instantly (no loading spinner). In the background, the library quietly re-fetches the data to see if it has changed (called 'stale-while-revalidate'). If it has, it seamlessly updates the UI.
Deduplication & Caching
Watch how a modern caching layer deduplicates multiple simultaneous requests, and how it instantly serves cached data on subsequent visits.
useEffect + fetch
useQuery
Using standard fetch (left) causes 3 separate network requests and loading spinners. Using a query cache (right) deduplicates the requests into a single network call. On remount, the cache serves data instantly while updating silently in the background.
Check yourself
Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.
Remember this
- Fetching data directly inside
useEffectis an anti-pattern for production. - Caching libraries (React Query, SWR) deduplicate requests based on a Query Key.
- They use a global cache to eliminate unnecessary loading spinners.
- The 'Stale-While-Revalidate' strategy shows old data instantly while fetching new data silently.
- They automatically handle race conditions, retries, and cache invalidation.
Done with this concept?
Mark it complete to track your progress. No login needed.