React-Apollo中如何轮询直到服务器返回指定值?
在React-Apollo中轮询直到获取特定响应的最简实现
当然可以实现!用Apollo Client自带的轮询控制API就能轻松搞定,不需要自己手动写复杂的定时器逻辑。下面我给你分享两种最简洁的实现方式,分别适配函数组件和类组件场景:
函数组件(推荐,React 16.8+)
利用useQuery钩子提供的startPolling和stopPolling方法,结合useEffect监听数据变化来控制轮询启停:
import { useQuery, gql } from '@apollo/client'; import { useEffect } from 'react'; const PING_QUERY = gql` query Ping { ping { response } } `; function MyComponent() { const { loading, error, data, startPolling, stopPolling } = useQuery(PING_QUERY, { pollInterval: 0, // 初始关闭自动轮询,我们手动控制 }); useEffect(() => { // 如果数据加载完成且状态不是OK,启动1秒一次的轮询 if (!loading && data?.ping?.response !== "OK") { startPolling(1000); } // 一旦拿到OK响应,立即停止轮询 else if (data?.ping?.response === "OK") { stopPolling(); // 这里可以添加拿到OK后的业务逻辑,比如弹窗提示、跳转页面等 } // 组件卸载时清理轮询,避免内存泄漏 return () => stopPolling(); }, [loading, data, startPolling, stopPolling]); if (loading) return <p>正在连接服务器...</p>; if (error) return <p>请求出错:{error.message}</p>; return ( <div> <p>当前服务器状态:{data.ping.response}</p> {data.ping.response === "OK" && <p>✅ 服务器已就绪!</p>} </div> ); }
逻辑说明:
- 初始设置
pollInterval: 0,避免自动启动轮询 - 通过
useEffect监听数据和加载状态的变化,动态控制轮询的启停 - 组件卸载时自动停止轮询,防止无效请求和内存泄漏
类组件(适配传统class写法)
如果你还在使用类组件,可以通过graphql高阶组件注入的data对象来调用轮询方法:
import { graphql, gql } from 'react-apollo'; import React from 'react'; const PING_QUERY = gql` query Ping { ping { response } } `; class MyComponent extends React.Component { componentDidMount() { // 组件挂载后立即启动1秒轮询 this.props.data.startPolling(1000); } componentDidUpdate(prevProps) { const currentStatus = this.props.data?.ping?.response; const prevStatus = prevProps.data?.ping?.response; // 当状态从非OK变为OK时,停止轮询 if (currentStatus === "OK" && prevStatus !== "OK") { this.props.data.stopPolling(); // 处理OK后的业务逻辑 } } componentWillUnmount() { // 组件卸载时清理轮询 this.props.data.stopPolling(); } render() { const { loading, error, ping } = this.props.data; if (loading) return <p>正在连接服务器...</p>; if (error) return <p>请求出错:{error.message}</p>; return ( <div> <p>当前服务器状态:{ping.response}</p> {ping.response === "OK" && <p>✅ 服务器已就绪!</p>} </div> ); } } export default graphql(PING_QUERY)(MyComponent);
逻辑说明:
- 组件挂载后启动轮询
- 在
componentDidUpdate中监听状态变化,一旦拿到OK响应就停止轮询 - 卸载时清理轮询,避免资源浪费
为什么这是最简方式?
Apollo Client的轮询API已经帮你处理了请求去重、缓存管理、请求取消等细节,比自己手动写setInterval+fetch要可靠得多,而且代码更简洁易维护。
内容的提问来源于stack exchange,提问作者xzhu
相关产品推荐
相关产品推荐

