You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-Query全局加载器:仅在初始请求后显示

实现不显示初始请求的全局加载器

要实现只在后台数据刷新时显示的全局加载器,避开初始页面加载的请求,可以通过以下几种方式处理:

方法一:给查询标记元数据,过滤初始请求

在定义useQuery时,给需要触发全局加载的后台请求添加自定义meta字段,然后在全局组件里用useIsFetching过滤仅包含该标记的请求:

// 业务组件中的查询,标记后台刷新请求
useQuery({
  queryKey: ['userData'],
  queryFn: fetchUserData,
  meta: { isBackgroundFetch: true }, // 自定义标记
})

全局加载器组件中:

import { useIsFetching } from '@tanstack/react-query'

function GlobalLoader() {
  // 只统计带有isBackgroundFetch标记的请求
  const isBackgroundFetching = useIsFetching({
    predicate: (query) => query.meta?.isBackgroundFetch === true
  })

  return isBackgroundFetching > 0 ? (
    <div className="global-loader">后台加载中...</div>
  ) : null
}

这种方式能精准控制哪些请求触发全局加载器,灵活性高。

方法二:利用缓存状态区分初始加载

初始加载的查询在缓存中是不存在的,而后台刷新是缓存已存在时的重新获取。可以自定义钩子判断全局后台获取状态:

import { useQueryClient, useIsFetching } from '@tanstack/react-query'

function useIsBackgroundFetching() {
  const queryClient = useQueryClient()
  const isFetching = useIsFetching()

  // 获取所有正在请求的queryKey
  const fetchingQueries = queryClient.getQueryCache().findAll({
    predicate: (query) => query.isFetching
  })

  // 判断每个正在请求的查询是否已有缓存数据
  const allHaveCache = fetchingQueries.every(query => {
    return queryClient.getQueryData(query.queryKey) !== undefined
  })

  // 正在请求且所有请求都已有缓存时,判定为后台刷新
  return isFetching > 0 && allHaveCache
}

// 全局加载器使用示例
function GlobalLoader() {
  const isBackgroundFetching = useIsBackgroundFetching()
  return isBackgroundFetching ? <div className="global-loader">后台加载中...</div> : null
}

这种方式无需给每个查询加标记,自动区分初始加载和后台刷新,适合多数场景。

方法三:结合已有页面级加载器状态

既然你已经有页面级初始加载器,可直接利用其状态屏蔽全局加载器的初始显示:

// App组件中组合两个加载器
function App() {
  const isPageLoading = usePageLoader() // 你的页面级加载状态

  return (
    <>
      <PageLoader isLoading={isPageLoading} />
      <GlobalLoader isDisabled={isPageLoading} />
      {/* 其他业务内容 */}
    </>
  )
}

// 全局加载器组件
function GlobalLoader({ isDisabled }) {
  const isFetching = useIsFetching()
  if (isDisabled || isFetching === 0) return null
  return <div className="global-loader">后台加载中...</div>
}

这种方式最简单直接,适合页面级加载与全局加载边界清晰的场景。

内容的提问来源于stack exchange,提问作者nullptr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:33:24