useQuery useQuery Data Fetching

Last updated: 2026-11-02

useQuery useQuery Data Fetching

useQuery from TanStack Query manages the whole request lifecycle plus the cache: it deduplicates automatically, refetches in the background, staleTime controls how long the data stays fresh, and invalidateQueries marks entries as stale so they refetch. The component only declares which data it needs and leaves the rest to the library, so the same query is never fetched twice for two components.

GroupData & Engineering
KindHook
SinceTanStack Query v5

ℹ️ Info The editor transpiles JSX to JavaScript and renders the real UI in a sandbox; components mount automatically — no manual render call needed.

📝 Syntax

import { useQuery } from '@tanstack/react-query'

const { data, isPending, isError, error, refetch } = useQuery({
  queryKey: ['todo', id],          // cache key: a change switches to or refetches the query
  queryFn: () => fetch('/api/todos/' + id).then(r => r.json()),
  staleTime: 30_000                // fresh for 30 seconds, no refetch needed
})
// isPending: first load without a cache; isFetching: any background refetch

⚙️ Parameters

queryKeyThe cache key (an array): in ['todos', id] a changed id switches to the matching cache entry and refetches, while an identical key reuses the cache.
staleTimeHow long the data stays fresh (milliseconds): within that window a remount uses the cache directly, afterwards a remount refreshes silently in the background (stale-while-revalidate).

Returns:Returns the query state such as { data, isPending, isError, error, refetch, isFetching }: data holds the latest data and refetch invalidates the entry and fetches it again manually.

▶ Example

The example runs out of the box: it auto-renders when expanded, and edits take effect instantly.

Output:

The first read waits 0.8 seconds; afterwards "Read" returns instantly because the Map cache hits, and "refetch" forces a new request and refreshes the cache - the core ideas behind staleTime and invalidation (simulated demo).

💡 Key Points

💡 Tip Put every dependency into the queryKey (['todos', filter, page]) and the library refetches automatically when they change - that is the dependency array of a useEffect handed over to the cache layer.
⚠️ Warning The queryKey must contain every request parameter and has to be serializable; leaving one out makes different data share one cache key and you get the wrong record under the wrong name.
ℹ️ Info v5 renamed loading to isPending: isPending means the first load without a cache while isFetching also covers a background refresh. The two mean different things.
More case studies coming soon.

📚 Related Tutorials

❓ FAQ

Q What is the difference between staleTime and gcTime (the former cacheTime)?
A staleTime decides for how long the data counts as fresh and needs no refetch, while gcTime decides how long an unused cache entry is kept before it is garbage collected. The first drives the request frequency, the second the memory usage.
Q How do I refresh the data after it changed?
A Call refetch(), or use queryClient.invalidateQueries({ queryKey }) to mark the related queries as stale, and the matching components refetch in the background automatically.
Q Why is the queryKey an array and not a string?
A An array is a structured key: ['todos', 2] and ['todos', 3] are told apart exactly, and you can invalidate every query under the ['todos'] prefix at once, which keeps the cache manageable in layers.
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏