Apollo graphql连接的React组件没有重新渲染

时间:2017-08-31 23:29:58

标签: reactjs graphql apollo apollo-client

我正在构建一个基于graphql的身份验证机制,我正在试图弄清楚为什么一个graphql连接的组件在重新登录后没有重新渲染...例如:

  • /users我有一个react-apollo graphql-connected用户组件,用于请求用户列表。
  • 如果没有提供令牌,服务器将返回身份验证错误;该组件向<Redirect>路由呈现/login;成功登录后,Login组件会存储令牌并重定向回来。
  • Users组件包装器启动graphql请求并在此期间呈现“loading ...”。当graphql请求成功时,它会重新呈现并且用户会出现,yay。
  • 如果您从该页面退出,则/logout处的Logout组件会丢弃该令牌,然后重定向回来; Users组件的请求再次获得身份验证错误,并将您发送到'/ login'。
  • 再次成功登录后,您将被发送回'/ users';再次启动对服务器的graphql请求(并呈现“loading ...”),但这次,当请求成功时,组件不会再次更新。

我可以看到graphql请求成功(并且已经在Chrome的调试器中观看,因为APOLLO_QUERY_RESULT操作由react-apollo的reducer处理并更新商店中的状态。)

我试图找到React正在检查组件的道具是否已经改变的地方,但我已经足够了一个React调试菜鸟,我还没知道在web检查器中找到该代码的位置:也许我不明白React是如何打包分发的。

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

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

1 个答案:

答案 0 :(得分:2)

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

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

我认为你不应该 这样做 - 我认为data.loading应该准确反映查询的状态,无论该选项是否设置为true ,与data.networkStatus不同,但looks like it's a known bug

至于resetStore - 它实际上并没有擦除整个商店,而是擦除您的商店重新获取所有有效查询。如果你想要吹掉你的商店,因为你已经将Redux与Apollo集成在一起,最简单的方法就是create an action to do that

您可能还需要考虑基于会话的身份验证机制,而不是依赖客户端来持久化令牌。实现服务器端非常简单,不仅需要在客户端执行较少的工作(不必记住在每个请求中传递令牌),并且会让您保留用户他们离开页面后登录。