正在加载,请稍候…

TanStack Query v5:React 服务端状态管理

掌握 TanStack Query v5——查询、变更、乐观更新、无限滚动和 SSR 预取。

TanStack Query v5:React 服务端状态管理

为什么选择 TanStack Query

服务端状态是异步的,可能过时,需要缓存。TanStack Query 处理所有这些。

TanStack Query v5:React 服务端状态管理 插图

设置 + 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,
  })
}

TanStack Query v5:React 服务端状态管理 插图

useMutation + 乐观更新

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'] }),
})

TanStack Query v5:React 服务端状态管理 插图

无限滚动

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) ?? []

-> 使用 JSON Viewer 调试 API 响应。