注销时无法清除apollo-client缓存



我已经阅读了一些其他的帖子以及一些github问题,我还没有找到一个解决方案。当我以一个用户身份注销,并以另一个用户身份登录时,新用户将在一瞬间出现,然后被前一个用户的数据所取代。

这是我在缓存上的核尝试:

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

我已经尝试从这两个位置获得客户端对象(我正在使用codegen):

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(),
});

当我用一个新用户登录时,我把query写入缓存。如果我记录从登录突变返回的数据,则数据是完美的,正是我想要写的:

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}`;

文档后,我不知道我的选择是什么,我曾经尝试过writeQuery,writeFragment,cache.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(),
});

事实上,我甚至不需要在登出时清除缓存

希望这篇文章能帮助到其他有类似经历的人。

最新更新