2017-08-31 60 views
3

我正在通过graphql构建一个身份验证机制,并试图找出为什么一个graphql连接组件在重新登录后不会重新渲染...例如:Apollo graphql-connected React组件不重新渲染

  • /users我有请求的用户的列表的反应-阿波罗graphql连接用户组件。
  • 如果未提供令牌,服务器将返回认证错误;该组件呈现至/login路线;登录成功后,Login组件将存储该令牌并重新导回。
  • 用户组件包装器启动graphql请求并在此期间呈现“正在加载...”。当graphql请求成功时,它会重新呈现并且用户出现,yay。
  • 如果您从该页面注销,则/logout的注销组件会丢弃该令牌,然后重新导回;用户组件的请求再次获取认证错误并将您发送到'/ login'。
  • 再次成功登录后,您将被发送回'/ users';它再次启动一个到服务器的graphql请求(并呈现“加载...”),但是这次,当请求成功时,组件不会再次更新。

我可以看到graphql请求成功(在Chrome的调试已经眼看着APOLLO_QUERY_RESULT动作由反应 - 阿波罗的减速处理,并在店里更新状态)。

我试着找到React在检查组件的道具是否已经改变,但我已经足够了React调试noob,我还没有想出在哪里可以在Web检查器中找到该代码:也许我不明白React如何打包发布。

我在登录和注销时都清除了ApolloClient的商店(通过调用resetStore()),因为我不想意外重复使用来自其他身份验证的数据;但是,删除这些调用并不能解决问题。有趣的是(?),如果我通过在graphql()调用中提供{ options: { fetchPolicy: 'network-only' } }来强制连接绕过缓存,问题就会消失。 (不是一个可行的解决方案 - 我想从缓存中普遍受益。)

我已经建立了一个精简的例子:https://github.com/bryanstearns/apollo-auth-experiment ,你可以看到它在CodeSandbox:https://codesandbox.io/s/m4nlpp86j(你可能会想从https://m4nlpp86j.codesandbox.io/的独立浏览器窗口访问正在运行的示例,因为沙盒编辑器有点让Web调试扩展很奇怪)。

回答

2

要修复此问题,请修改graphql HOC以在选项中包含notifyOnNetworkStatusChange

export const Users = graphql(usersQuery, { options: { notifyOnNetworkStatusChange: true } })(RawUsers); 

我不认为你应该做到这一点 - 我认为data.loading应该准确反映您的查询的状态,无论该选项被设置为true,不像data.networkStatuslooks like it's a known bug

只要resetStore - 它实际上并没有擦掉你的整个商店,而是将你的商店擦掉重新提交所有活动查询。如果你想吹掉你的店铺,因为你已经将Redux和Apollo整合在一起,最简单的做法是create an action to do that

您可能还想考虑基于会话的身份验证机制,而不是依赖客户端来持久保存令牌。实现服务器端非常简单,不仅需要在客户端进行更少的工作(不必在每次请求时都要记住传递令牌),并且可以让用户在离开后保持登录状态从页面。

+0

非常好,Daniel,谢谢 - 这解决了我的问题,并且阅读了您链接到的问题的历史......教育:-)。我可能会切换到cookie认证;这也是我第一次使用localStorage进行的实验。令牌具有跨多个域的优势(尽管这还不是问题),Apollo可以轻松地为所有请求进行全局配置:https://github.com/bryanstearns/apollo-auth-experiment/blob /ac05f47ace4fe00f346cbacde8d342306b6b94e0/src/index.js#L31 –

相关问题