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
相关产品推荐
相关产品推荐

