Apollo Client useQuery钩子始终处于loading状态问题求助
useQuery钩子loading状态始终为true的排查与解决方法
问题概述
使用@apollo/client的useQuery钩子调用GraphQL API时,loading属性始终为true,导致自定义Loader持续显示。最初同时调用多个useQuery出现该问题,后续单个查询也复现此状态,版本匹配(@apollo/client@3.8.7 + React 18.2.0 + React Native 0.72.6),常规版本相关解决方案无效。
排查步骤与解决方案
1. 验证Apollo Client基础配置
- 确认ApolloProvider包裹范围:确保
ApolloProvider在应用最外层(如App.tsx)包裹所有导航组件(抽屉导航->标签导航->栈导航),否则组件无法获取Apollo Client实例,请求无法正常发起。 - 检查HttpLink配置:确认
HttpLink的uri指向正确的GraphQL API地址,若后端需要认证,需配置authLink携带必要的请求头(如Token):
import { ApolloClient, InMemoryCache, ApolloProvider, createHttpLink } from '@apollo/client'; import { setContext } from '@apollo/client/link/context'; const httpLink = createHttpLink({ uri: 'https://your-api-domain/graphql', // 替换为实际API地址 }); // 认证链路(按需添加) const authLink = setContext((_, { headers }) => ({ headers: { ...headers, authorization: `Bearer ${your_auth_token}`, // 替换为实际认证Token }, })); const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache(), }); // 在App.tsx中使用ApolloProvider包裹导航 export default function App() { return ( <ApolloProvider client={client}> {/* 你的导航组件 */} </ApolloProvider> ); }
2. 确认请求是否实际发送
添加请求日志链路,查看请求详情:
import { ApolloLink } from '@apollo/client'; import { onError } from '@apollo/client/link/error'; import logger from 'apollo-link-logger'; // 拼接日志链路与错误处理链路 const client = new ApolloClient({ link: ApolloLink.from([ logger, // 打印请求/响应详情 onError(({ graphQLErrors, networkError }) => { if (graphQLErrors) { graphQLErrors.forEach(err => console.log('GraphQL错误:', err)); } if (networkError) console.log('网络错误:', networkError); }), authLink.concat(httpLink), ]), cache: new InMemoryCache(), });
通过控制台日志确认:
- 请求是否发送到正确的API地址
- 后端是否返回响应(成功/失败)
- 是否存在GraphQL语法错误或网络异常
3. 简化测试单个查询
暂时注释其他useQuery调用,仅保留单个查询,并开启notifyOnNetworkStatusChange查看详细网络状态:
const { loading, data, error, networkStatus } = useQuery(query.GET_COLLECTIONS_BY_HANDLE.query, { variables: { handle: 'hair' }, notifyOnNetworkStatusChange: true, }); console.log('查询状态:', { loading, data, error, networkStatus });
networkStatus对应状态参考:
- 1: 请求中(loading)
- 7: 请求成功
- 5: 网络错误
- 6: 解析错误
若networkStatus一直停留在1,说明请求未完成;若为5/6,需对应排查网络或后端返回格式问题。
4. 检查组件渲染稳定性
添加监听确认组件是否被反复挂载/卸载:
import { useEffect } from 'react'; const Home = () => { useEffect(() => { console.log('Home组件挂载'); return () => console.log('Home组件卸载'); }, []); // ... 其他代码 };
若控制台反复打印挂载/卸载日志,说明导航配置或父组件状态导致组件频繁重建,useQuery会反复发起请求,导致loading始终为true,需调整导航或状态逻辑。
5. 验证查询与变量正确性
直接在GraphQL Playground/Postman中测试查询语句与变量:
# 替换为你的查询语句 query GetCollectionsByHandle($handle: String!) { collection(handle: $handle) { id # 其他需要的字段 } }
传入变量{"handle": "hair"},确认后端是否能正常返回数据。若后端返回异常或字段不匹配,需调整查询语句或联系后端修复。
6. React Native特殊排查
- 网络权限:Android需在
AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET" />;iOS若使用HTTP请求,需在Info.plist中配置NSAppTransportSecurity允许非HTTPS请求。 - 调试代理:若使用Charles等代理工具,需确保设备与代理处于同一网络,且证书配置正确,避免请求被拦截。
内容的提问来源于stack exchange,提问作者Khushal Sonawat
相关产品推荐
相关产品推荐

