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

React Query中如何判断查询视图状态、按需更新及获取视图查询列表?

判断查询是否处于视图及获取活跃查询列表的实用方案

一、判断单个查询是否在视图中(无需全局状态)

1. 针对“查询被组件活跃使用”的场景

如果用的是React Query这类查询管理库,可直接通过查询实例的isActive状态判断——该状态为true时,说明当前有组件在订阅该查询(即对应组件处于挂载/活跃状态)。

代码示例:

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

// 在组件或逻辑中
const queryClient = useQueryClient();
const isXQueryActive = queryClient.getQueryState('x')?.isActive;

// 仅当活跃时触发更新
if (isXQueryActive) {
  queryClient.refetchQueries(['x']);
}

2. 针对“组件在浏览器视口内可见”的场景

若要精准判断组件是否在用户可视区域,用Intersection Observer API即可,无需全局状态,每个组件独立管理可视状态:

import { useEffect, useState, useRef } from 'react';
import { useQuery } from '@tanstack/react-query';

function XQueryComponent() {
  const [isInViewport, setIsInViewport] = useState(false);
  const componentRef = useRef(null);

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => setIsInViewport(entry.isIntersecting),
      { threshold: 0.1 } // 可视占比达10%时判定为在视图中,可按需调整
    );
    if (componentRef.current) observer.observe(componentRef.current);
    return () => observer.disconnect();
  }, []);

  // 仅在视图中时自动刷新查询
  const { data } = useQuery({
    queryKey: ['x'],
    queryFn: fetchXData,
    refetchInterval: isInViewport ? 3000 : false, // 可视时每3秒刷新,否则停止
  });

  return <div ref={componentRef}>{/* 渲染查询内容 */}</div>;
}

二、获取处于视图中的查询列表

1. 获取所有活跃订阅的查询列表

利用React Query的API,通过getQueries()拿到所有查询实例,再筛选出isActive为true的:

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

const queryClient = useQueryClient();
const activeQueries = queryClient.getQueries().filter(q => q.state.isActive);
const activeQueryKeys = activeQueries.map(q => q.queryKey);
// activeQueryKeys即为当前被组件活跃使用的查询键列表

2. 获取视口内可见的查询列表

用React Context管理可视查询集合,比全局状态更优雅:

// 第一步:创建Context管理可视查询
import { createContext, useContext, useState } from 'react';

const VisibleQueriesContext = createContext({
  addKey: () => {},
  removeKey: () => {},
  visibleKeys: new Set()
});

export function VisibleQueriesProvider({ children }) {
  const [visibleKeys, setVisibleKeys] = useState(new Set());

  const addKey = (key) => {
    setVisibleKeys(prev => new Set([...prev, key]));
  };

  const removeKey = (key) => {
    setVisibleKeys(prev => {
      const newSet = new Set(prev);
      newSet.delete(key);
      return newSet;
    });
  };

  return (
    <VisibleQueriesContext.Provider value={{ addKey, removeKey, visibleKeys }}>
      {children}
    </VisibleQueriesContext.Provider>
  );
}

// 第二步:在查询组件中注册可视状态
export function XQueryComponent() {
  const { addKey, removeKey } = useContext(VisibleQueriesContext);
  const componentRef = useRef(null);

  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      entry.isIntersecting ? addKey('x') : removeKey('x');
    });
    if (componentRef.current) observer.observe(componentRef.current);
    
    // 组件卸载时清理
    return () => {
      observer.disconnect();
      removeKey('x');
    };
  }, [addKey, removeKey]);

  return <div ref={componentRef}>{/* 内容 */}</div>;
}

// 第三步:在需要获取列表的地方使用
export function QueryStatusComponent() {
  const { visibleKeys } = useContext(VisibleQueriesContext);
  return (
    <div>
      当前可视查询:{Array.from(visibleKeys).join(', ')}
    </div>
  );
}

内容的提问来源于stack exchange,提问作者Siva rama krishna Bethu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 08:45:46