繁体   English   中英

注销时无法清除阿波罗客户端缓存

[英]Unable to clear apollo-client cache on logout

我已经阅读了其他几篇文章以及一些 github 问题,但我还没有找到解决方案。 当我以一个用户身份注销并以另一个用户身份登录时,新用户会出现一瞬间,然后被前一个用户的数据替换。

下面是我尝试在 go 核上缓存:

onClick={() => {
  client
    .clearStore()
    .then(() => client.resetStore())
    .then(() => client.cache.reset())
    .then(() => client.cache.gc())
    .then(() => dispatch(logoutUser))
    .then(() => history.push('/'));
}}

我尝试从这两个位置获取客户端 object(我正在使用代码生成器):

const { data, loading, error, client } = useUserQuery();
const client = useApolloClient();

这是我的 Apollo 客户端设置:

const apolloClient = new ApolloClient({
  uri: config.apiUrl,
  headers: {
    uri: 'http://localhost:4000/graphql',
    Authorization: `Bearer ${localStorage.getItem(config.localStorage)}`, 
  },
  cache: new InMemoryCache(),
});

当我使用新用户登录时,我将查询写入缓存。 如果我记录从登录突变返回的数据,数据是完美的,正是我想写的:

sendLogin({
  variables: login,
  update: (store, { data }) => {
    store.writeQuery({
      query: UserDocument,
      data: { user: data?.login?.user },
    });
  },
})

UserDocument 是从 codegen 生成的:

export const UserDocument = gql`
    query user {
  user {
    ...UserFragment
  }
}
    ${UserFragmentFragmentDoc}`;

按照文档,我不明白我的选择是什么,我尝试了 writeQuerywriteFragmentcache.modify并且没有任何变化。 身份验证部分似乎暗示了我正在尝试的同一件事。

似乎我所能做的就是对用户强制执行window.location.reload()这很荒谬,必须有办法。

好吧,一部分的我觉得自己像个笨蛋,另一部分认为文档中有一些误导性信息。

尽管这个链接说:

const client = new ApolloClient({
  cache,
  uri: 'http://localhost:4000/graphql',
  headers: {
    authorization: localStorage.getItem('token') || '',
    'client-name': 'Space Explorer [web]',
    'client-version': '1.0.0',
  },
  ...
});

这些选项在后台传递到一个新的 HttpLink 实例中,然后将 ApolloClient 配置为使用该实例。

这不是开箱即用的。 本质上发生的事情是我的令牌被锁定在 apollo 提供者中并且永远不会更新,因此返回的有效负载成功更新了我的缓存但是因为令牌仍然包含旧的 userId,查询订阅覆盖了新用户的新数据登录。 这就是刷新有效的原因,因为它强制客户端使用我的本地存储重新渲染。

修复非常简单:

  // headerLink :: base headers for graphql queries
  const headerLink = new HttpLink({ uri: 'http://localhost:4000/graphql' });

  // setAuthorizationLink :: update headers as localStorage changes
  const setAuthorizationLink = setContext((request, previousContext) => {
    return {
      headers: {
        ...previousContext.headers,
        Authorization: `Bearer ${localStorage.getItem(config.localStorage)}`,
      },
    };
  });

  // client :: Apollo GraphQL Client settings
  const client = new ApolloClient({
    uri: config.apiUrl,
    link: setAuthorizationLink.concat(headerLink),
    cache: new InMemoryCache(),
  });

事实上,我什至不需要在注销时清除缓存。

希望这可以帮助其他可能以类似方式挣扎的人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM