Capítulo 13 de 80

Chapter 13: Query Options

Core Idea

queryOptions() is a pass-through helper (returns exactly what you give it at runtime) whose only job is preserving TypeScript inference when queryKey/queryFn/options are extracted into a shared function used from multiple call sites.

Key Concepts

  • Why it exists: extracting { queryKey, queryFn, ...} into a plain function loses type inference at usage sites; wrapping the return in queryOptions() keeps it, including a queryKey that "remembers" its associated data type for queryClient.getQueryData.
  • Shared across every consumer: the same options object works with useQuery, useSuspenseQuery, useQueries, queryClient.query(), and queryClient.setQueryData() — one definition, every entry point.
  • Infinite queries get their own helper: infiniteQueryOptionsqueryOptions itself is not used for infinite queries.
  • Component-level override pattern: spread shared options into useQuery and add a per-component select to reshape the data without touching the shared definition.

Code Examples

function groupOptions(id: number) {
  return queryOptions({
    queryKey: ['groups', id],
    queryFn: () => fetchGroups(id),
    staleTime: 5 * 1000,
  })
}

useQuery(groupOptions(1))
useSuspenseQuery(groupOptions(5))
useQueries({ queries: [groupOptions(1), groupOptions(2)] })
queryClient.setQueryData(groupOptions(42).queryKey, newGroups)

// Per-component override: same shared options, different derived shape
const query = useQuery({ ...groupOptions(1), select: (data) => data.groupName })
  • What it demonstrates: one groupOptions definition reused across useQuery, useSuspenseQuery, useQueries, and direct queryClient calls, plus a component-local select override on top.

Key Takeaways

  1. Reach for queryOptions the moment a queryKey/queryFn pair is used from more than one place — it's the difference between typed and unknown at every call site.
  2. queryOptions() does nothing at runtime; its entire value is TypeScript inference, so it's free to add.
  3. Use infinite queries' own infiniteQueryOptions helper, not this one.

Connects To

  • TypeScript: fuller explanation of the inference mechanics.
  • Render Optimizations: the select pattern shown here in the override example.