React Apollo:如何在单个pollInterval下执行多个查询
在React Apollo中使用单个定时器轮询多个查询
好问题!你当前的写法确实会为每个查询创建独立的定时器,这显然不是最高效的方式。React Apollo本身没有直接支持你设想的那种“传查询数组+单轮询配置”的写法,但我们有两种靠谱的方案来实现单一定时器下的多查询轮询:
方案一:手动管理轮询定时器
我们可以借助Apollo Client的query方法,自己创建一个定时器,在每次触发时统一执行所有查询的获取操作,完全掌控轮询节奏:
import { useApolloClient } from '@apollo/client'; import { useEffect, useState } from 'react'; function YourComponent() { const client = useApolloClient(); const [query1Data, setQuery1Data] = useState(null); const [query2Data, setQuery2Data] = useState(null); // 定义统一获取所有数据的函数 const fetchAllQueries = async () => { try { // 并行执行多个查询,用Promise.all优化性能 const [result1, result2] = await Promise.all([ client.query({ query: QUERY_1 }), client.query({ query: QUERY_2 }) ]); setQuery1Data(result1.data); setQuery2Data(result2.data); } catch (error) { // 统一处理查询错误 console.error('轮询查询失败:', error); } }; useEffect(() => { // 组件挂载时先执行一次查询 fetchAllQueries(); // 设置10秒间隔的轮询定时器 const pollInterval = setInterval(fetchAllQueries, 10000); // 组件卸载时清除定时器,避免内存泄漏 return () => clearInterval(pollInterval); }, [client]); // 你的组件渲染逻辑... return ( <div> {/* 渲染query1Data和query2Data */} </div> ); }
这个方案的优势是完全自定义轮询逻辑,所有查询共享同一个定时器,避免了多定时器的资源浪费。
方案二:合并多个GraphQL查询(推荐)
如果你的后端GraphQL服务支持,把多个查询合并成一个单独的查询是更简洁的方式,这样就能直接使用React Apollo原生的pollInterval配置了:
首先编写合并后的查询(可以用片段来复用原有查询的字段):
import { gql } from '@apollo/client'; const COMBINED_QUERY = gql` query CombinedPollingQuery { # 复用QUERY_1的字段 ...Query1Content # 复用QUERY_2的字段 ...Query2Content } # 对应QUERY_1的字段片段 fragment Query1Content on Query { products { id name price } } # 对应QUERY_2的字段片段 fragment Query2Content on Query { currentUser { id username email } } `;
然后在组件中使用这个合并后的查询:
import { compose, graphql } from 'react-apollo'; const YourComponent = ({ data }) => { const { products, currentUser } = data; // 渲染逻辑... }; export default compose( graphql(COMBINED_QUERY, { options: { pollInterval: 10000 } }) )(YourComponent);
这种方式完全利用Apollo的原生轮询机制,不需要手动管理定时器,代码更简洁易维护,是优先推荐的方案。
需要注意的是,你设想的那种直接向graphql HOC传入查询数组的写法,目前React Apollo并没有支持,所以上面两种方案是实现需求的可行路径。
内容的提问来源于stack exchange,提问作者Eesa
相关产品推荐
相关产品推荐

