Apollo graphql 连接的 React 组件不会重新渲染

Apollo graphql-connected React component isn't rerendering

我正在致力于通过 graphql 构建身份验证机制,并且我正在尝试弄清楚为什么 graphql 连接的组件在重新登录后没有重新呈现...例如:

我可以看到 graphql 请求成功(并且在 Chrome 的调试器中观察到 APOLLO_QUERY_RESULT 操作由 react-apollo 的 reducer 处理并更新存储中的状态)。

我试图找到 React 正在检查组件的 props 是否已更改的位置,但我是一个 React 调试菜鸟,我还不知道在 Web 检查器中在哪里可以找到该代码: 也许我不明白 React 是如何打包分发的。

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

我构建了一个精简示例:https://github.com/bryanstearns/apollo-auth-experiment 您可以在 CodeSandbox 中看到它:https://codesandbox.io/s/m4nlpp86j (you'll probably want to access the running example from an independent browser window at https://m4nlpp86j.codesandbox.io/ 因为沙盒编辑器有点让 Web 调试扩展行为怪异)。

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

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

我认为您不应该 这样做 -- 我认为 data.loading 应该准确反映您的查询状态,而不管该选项是设置为真,不像 data.networkStatus 但它 looks like it's a known bug.

至于 resetStore -- 它实际上并没有擦除您的整个商店,而是擦掉您的商店 并且 重新获取您所有的活动查询。如果你想炸毁你的商店,因为你已经将 Redux 与 Apollo 集成,最简单的做法是 .

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