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

useLazyQuery执行clearStore/resetStore后仍返回旧数据求助

Apollo Client登出后clearStore无法清除useLazyQuery旧数据问题解决

问题描述

登出用户时调用client.clearStore()清除缓存后,useLazyQuery返回的data对象仍保留旧用户数据,即使后续请求API返回[Error: Unauthorized],多次执行登出操作且不重启应用也无法清除该旧数据。使用版本:apollo 3.7.0、expo 46.0.16、react-native 0.69.6、react 18.0.0。

相关代码:

const client = useApolloClient();
const [getMe, { loading, error, data }] = useLazyQuery(q, {
  fetchPolicy: 'network-only',
});
React.useEffect(() => {
    getMe();
  }, [isLoggedIn, getMe]);

const onRefresh = async () => {
    dispatch(logout());
    await client.clearStore();
    console.log(data);
  };

原因分析

clearStore()仅清除Apollo Client的缓存,但不会自动重置useLazyQuery在组件内部维护的data状态。同时,登出后isLoggedIn状态变化触发的getMe()请求会返回错误,但组件未处理错误状态对应的data重置,导致旧数据一直保留。

解决方案

1. 调用查询的reset函数手动重置状态

useLazyQuery返回的reset函数可以直接重置查询的data、loading、error状态,配合clearStore()使用:

const [getMe, { loading, error, data, reset }] = useLazyQuery(q, {
  fetchPolicy: 'network-only',
});

const onRefresh = async () => {
  dispatch(logout());
  await client.clearStore();
  reset(); // 重置查询状态
  console.log(data); // 此时data为undefined
};

2. 根据isLoggedIn状态自动重置

在useEffect中判断isLoggedIn状态,当用户登出(状态为false)时直接重置查询,无需执行无效请求:

const [getMe, { loading, error, data, reset }] = useLazyQuery(q, {
  fetchPolicy: 'network-only',
});

React.useEffect(() => {
  if (isLoggedIn) {
    getMe();
  } else {
    reset(); // 登出时重置查询状态
  }
}, [isLoggedIn, getMe, reset]);

const onRefresh = async () => {
  dispatch(logout());
  await client.clearStore();
};

3. 使用resetStore()替代clearStore()

resetStore()会清除缓存并重新执行所有活跃查询,能确保组件状态与缓存同步更新,比clearStore()更彻底:

const onRefresh = async () => {
  dispatch(logout());
  await client.resetStore(); // 替换clearStore
  // 此时getMe会重新执行,因未授权返回错误,data会被更新为undefined
};

内容的提问来源于stack exchange,提问作者lulu33

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 10:02:21