正在加载,请稍候…

TanStack Query v5: Server State Management for React

Master TanStack Query v5 — queries, mutations, optimistic updates, infinite scroll, and SSR prefetching.

Why TanStack Query

Server state is async, can go stale, needs caching. TanStack Query handles all of this.

Setup + useQuery

const [qc] = useState(() => new QueryClient({ defaultOptions: { queries: { staleTime: 60_000 } } }))

function usePost(id) {
  return useQuery({
    queryKey: ['posts', id],
    queryFn: () => fetch('/api/posts/' + id).then(r => r.json()),
    enabled: id > 0,
  })
}

useMutation + Optimistic Update

const mutation = useMutation({
  mutationFn: (data) => fetch('/api/posts', { method: 'POST', body: JSON.stringify(data) }).then(r => r.json()),
  onMutate: async (newPost) => {
    await queryClient.cancelQueries({ queryKey: ['posts'] })
    const prev = queryClient.getQueryData(['posts'])
    queryClient.setQueryData(['posts'], old => [...(old || []), { ...newPost, id: 'temp' }])
    return { prev }
  },
  onError: (_, __, ctx) => queryClient.setQueryData(['posts'], ctx?.prev),
  onSettled: () => queryClient.invalidateQueries({ queryKey: ['posts'] }),
})

Infinite Scroll

const { data, fetchNextPage, hasNextPage } = useInfiniteQuery({
  queryKey: ['posts'],
  queryFn: ({ pageParam = 1 }) => fetch('/api/posts?page=' + pageParam).then(r => r.json()),
  getNextPageParam: last => last.nextPage,
  initialPageParam: 1,
})
const posts = data?.pages.flatMap(p => p.posts) ?? []

-> Debug API responses with the JSON Viewer.