TanStack Query and frontend state
Budget: 1 week.
Why this matters
Today App.jsx manually fetches sessions and scenarios with useEffect and
local useState. The second the product has features like "save scenario,
list my scenarios, compare across runs," ad-hoc fetch calls fall apart.
You end up reimplementing caching, loading flags, refetch-on-focus, and
optimistic updates by hand. TanStack Query does all of that and is the
default choice for new React apps.
What to learn
| Topic | Time |
|---|---|
useQuery for reads, with a typed fetch client | 1 day |
| Query keys: how to design them so invalidation is surgical | 0.5 day |
useMutation for writes, and when to invalidateQueries vs return new data | 1 day |
| Optimistic updates for mutations that should feel instant | 0.5 day |
Defaults: stale time, retry, refetchOnWindowFocus, and when to override | 0.5 day |
| Devtools: installing and reading the TanStack Query devtools panel | 0.5 day |
Port every useEffect-based fetch in App.jsx to useQuery or useMutation | 2-3 days |
Resources
- TanStack Query docs: the official reference.
- Practical React Query by TkDodo: the best long-form treatment, read as a series.
- TanStack Query devtools: install and keep open while porting.
Exercise
Replace every useEffect(() => fetch(...)) in App.jsx and the hooks in
frontend/src/ with useQuery. Replace every POST or PATCH call with
useMutation. When a scenario is created or renamed, invalidate the
scenario list query instead of manually reloading. Keep the SSE chat stream
as is. TanStack Query is for request/response, not for streams.