Apollo Graphql刷新token成功后useQuery未更新数据如何解决?
排查思路
- 首先检查重试请求的执行链路:确认token刷新成功后,重试的
GET_USER_INFO请求是否携带了正确的新token,是否收到了正常的响应数据。 - 排查刷新token请求是否触发了重复错误处理:你当前用全局client调用刷新token的mutation,该请求会走同一套errorLink逻辑,如果刷新接口也返回401,会触发循环重试,产生额外的失败请求。
- 检查useQuery的更新逻辑:默认配置下useQuery仅在缓存数据变化时通知组件更新,重试请求的状态变化默认不会触发组件重新渲染,可能导致你感知不到数据更新。
- 验证缓存写入是否正常:确认重试请求返回的用户数据是否正确写入了Apollo Client缓存,是否存在缓存命中导致不更新的问题。
解决方案
- 给刷新token的请求添加跳过错误处理标识,避免循环重试
修改getNewToken中调用mutate的逻辑,新增context参数跳过errorLink处理:
return client.mutate({ mutation: REFRESH_TOKEN, variables:{ refreshTokenRefreshToken : refreshToken, }, context: { skipErrorHandler: true } })
同时在errorLink开头添加判断,跳过对应请求的错误处理:
const errorLink = onError( ({ graphQLErrors, networkError, operation, forward }) => { // 跳过刷新token请求的错误处理,避免死循环 if (operation.getContext().skipErrorHandler) { return forward(operation) } // 原有逻辑保持不变 if (graphQLErrors) { for (let err of graphQLErrors) { switch (err.extensions?.code) { case "UNAUTHENTICATED" : // 原有逻辑 } } } } )
- 调整useQuery配置,确保重试后数据能同步到组件
给GET_USER_INFO的useQuery添加状态变化通知配置:
const { data:dataGetUserInfo, loading:loadingQuery, error:errorQuery,refetch } = useQuery(GET_USER_INFO, { variables: { getUserInfoInfoId: userId }, notifyOnNetworkStatusChange: true, // 网络请求状态变化时触发组件更新 fetchPolicy: 'cache-and-network' // 按需调整,避免纯缓存策略导致的不更新 });
- 优化重试逻辑,避免header冲突
你已经在getNewToken中将新token存入了localStorage,authLink会自动读取最新的token,无需在errorLink中手动修改请求header,修改对应逻辑即可:
.flatMap(() => { // 移除手动设置header的代码,authLink会自动拼接最新token return forward(operation); });
- 完善错误兜底
在getNewToken的catch逻辑中抛出错误并跳转登录页,避免无效请求继续发起:
.catch((err)=>{ console.log(err) localStorage.clear() // 替换为你项目的登录页地址 window.location.href = '/login' return Promise.reject(err) })
内容的提问来源于stack exchange,提问作者Maria Raiven
相关产品推荐
相关产品推荐

