Capítulo 43 de 80
v3 split the single monolithic QueryCache into a QueryClient (configuration + interaction surface) plus separate lower-level QueryCache/MutationCache instances, and replaced the old provider/hook names with QueryClientProvider/useQueryClient — the API shape that every later version builds on.
QueryClient split: new QueryClient() auto-creates a QueryCache and MutationCache if you don't supply your own — enabling multiple clients to share one cache, and easier testing of each piece in isolation.ReactQueryConfigProvider/ReactQueryCacheProvider → QueryClientProvider; default query/mutation options move into new QueryClient({ defaultOptions: { queries, mutations } }) (renamed from defaultConfig).QueryCache/QueryClient must always be explicitly constructed — there's no implicit global one.QueryCache.prefetchQuery() → QueryClient.prefetchQuery() (still returns no data — use the new QueryClient.fetchQuery() if you need the resolved value); QueryCache.getQuery()/getQueries() → QueryCache.find()/findAll(); QueryCache.isFetching (property) → QueryClient.isFetching() (function); useQueryCache → useQueryClient; ReactQueryErrorResetBoundary → QueryErrorResetBoundary/useQueryErrorResetBoundary.select, per-query/mutation default configuration, the variable-length useQueries hook, mutation retry/offline/replay support, and bundled devtools.QueryClient/QueryClientProvider shape still used today — later migrations (v4, v5) build on this structure rather than replacing it.fetchQuery (returns data) vs. prefetchQuery (doesn't) was introduced here as a distinction that persisted, in spirit, through v5's queryClient.query() unification.