Capítulo 40 de 80

Chapter 40: Default Query Function

Core Idea

Registering a queryFn on the QueryClient's defaultOptions.queries lets every query in the app be defined by just its queryKey — a common pattern when a single generic fetcher (e.g. one hitting a REST base URL with the key as the path) can serve most of the app.

Key Concepts

  • Registration: pass queryFn inside new QueryClient({ defaultOptions: { queries: { queryFn: defaultQueryFn } } })defaultQueryFn receives the same QueryFunctionContext (including queryKey) any query function would.
  • Usage becomes key-only: useQuery({ queryKey: ['/posts'] }) needs no queryFn at all once a default is registered; the key doubles as the request path/identifier in this pattern.
  • Per-query override still works: any query can still supply its own explicit queryFn to bypass the default — registering a default doesn't remove that option.

Code Examples

const defaultQueryFn = async ({ queryKey }) => {
  const { data } = await axios.get(`https://api.example.com${queryKey[0]}`)
  return data
}

const queryClient = new QueryClient({
  defaultOptions: { queries: { queryFn: defaultQueryFn } },
})

// No queryFn needed — the key IS the request
function Posts() {
  const { data } = useQuery({ queryKey: ['/posts'] })
}
  • What it demonstrates: a REST-path-shaped default query function turning every useQuery call site into just a key.

Key Takeaways

  1. This pattern fits best when query keys naturally map to request paths (REST-ish APIs) — it doesn't generalize as cleanly to GraphQL or heterogeneous fetch logic.
  2. A registered default doesn't lock every query into using it — pass an explicit queryFn per call to override when needed.

Connects To

  • Query Functions: the general queryFn contract this default still has to satisfy.
  • QueryClient: where defaultOptions lives.