标准答案

  1. 它管理的是服务端状态,不是用来替代所有本地 UI 状态。
  2. queryKey 用来描述一份数据的身份,参数变化时应进入 queryKey,避免缓存串用。
  3. 它可以自动处理请求去重、缓存时间、stale 状态、窗口聚焦刷新和失败重试。
  4. mutation 适合创建、更新、删除等写操作,并可以配合 invalidateQueries 或乐观更新刷新相关数据。
  5. 和 Redux 这类客户端状态库相比,它更专注接口数据生命周期。

题目解析

这道题要先讲清“服务端状态”和“客户端状态”的边界。接口列表、详情和分页属于服务端状态,弹窗开关和输入框草稿通常是客户端状态。

TanStack Query 的价值不只是少写 useEffect,而是把缓存、失效、刷新和错误重试变成统一机制。

使用时要设计好 queryKey 和失效范围,否则缓存命中和刷新都会变得不可预测。

代码示例

下面通过 queryKey 把搜索参数纳入缓存身份,删除后让用户列表重新失效。

TSX
function UsersPage({ keyword }: { keyword: string }) {
  const queryClient = useQueryClient()
  const usersQuery = useQuery({
    queryKey: ['users', { keyword }],
    queryFn: () => fetchUsers(keyword)
  })
  const deleteUser = useMutation({
    mutationFn: deleteUserById,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['users'] })
    }
  })

  if (usersQuery.isLoading) return <PageSkeleton />
  if (usersQuery.isError) return <ErrorState onRetry={() => usersQuery.refetch()} />

  return <UserList users={usersQuery.data} onDelete={deleteUser.mutate} />
}

常见误区

  • 把弹窗开关、表单输入值等本地 UI 状态也塞进 React Query。
  • queryKey 设计过粗,搜索条件或分页变化后仍复用旧缓存。
  • 写操作成功后没有失效相关 query,页面继续展示旧数据。

作者信息