Capítulo 3 de 80
The entire library boils down to three concepts used together: queries (read), mutations (write), and query invalidation (tell the cache a write changed something so reads refresh).
useQuery({ queryKey, queryFn }) reads/subscribes to cached async data.useMutation({ mutationFn }) performs an async write and exposes a .mutate() trigger plus lifecycle callbacks (onSuccess, etc.).queryClient.invalidateQueries({ queryKey }), typically called from a mutation's onSuccess, marks matching cached queries stale so they refetch.QueryClient instance, provided once via QueryClientProvider at the app root; useQueryClient() retrieves it anywhere below.const queryClient = new QueryClient()
function App() {
return (
<QueryClientProvider client={queryClient}>
<Todos />
</QueryClientProvider>
)
}
function Todos() {
const queryClient = useQueryClient()
const query = useQuery({ queryKey: ['todos'], queryFn: getTodos })
const mutation = useMutation({
mutationFn: postTodo,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
})
return (
<div>
<ul>{query.data?.map((todo) => <li key={todo.id}>{todo.title}</li>)}</ul>
<button onClick={() => mutation.mutate({ id: Date.now(), title: 'Do Laundry' })}>
Add Todo
</button>
</div>
)
}
queryClient.invalidateQueries in a mutation's onSuccess is the default, idiomatic way to keep reads in sync with writes — reach for manual cache writes only when invalidation is provably too slow.useQueryClient() is how any component below the provider reaches the shared cache without prop drilling.