What is client-side data fetching?
It is how the client talks to your API: requesting data, showing loading and error states, caching responses, and keeping the UI in sync with the server. TanStack Query handles caching, deduplication, and refetching so you do not hand-roll it with effects.
Why it matters
The client and server meet here, at the fetch. Done well, the UI feels fast and stays consistent; done badly, you get spinners everywhere, stale data, and duplicate requests. Since you own both ends, you can design the API and the fetching together — a full-stack advantage.
What to learn
- Fetching with
fetchand with TanStack Query - Server state versus client state
- Loading, error, and success handling
- Caching and background refetch
- Mutations and invalidating the cache
- Optimistic updates
- Designing the API for easy client consumption
Common pitfall
Hand-rolling fetching with useEffect and useState on every component:
manual loading flags, no caching, refetch on every mount, race conditions when
responses arrive out of order. A query library solves all of this. Reinventing it
by hand is the classic source of flaky client data bugs.
Resources
Primary (free):
- TanStack Query — Overview · docs
- MDN — Using fetch · docs
- TanStack Query — Mutations · docs
Practice
Fetch a list from your own API with TanStack Query, rendering loading, error, and success states with caching. Add a mutation that updates the server and invalidates the cache so the UI refreshes. Done when navigating away and back serves cached data instantly while refetching in the background.
Outcomes
- Fetch with caching, dedup, and background refetch.
- Distinguish server state from client state.
- Render loading, error, and success states.
- Mutate and invalidate to keep the UI in sync.