首页 文章

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

提问于
浏览
3

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

  • /users 我有一个react-apollo graphql-connected用户组件,它请求用户列表 .

  • 如果没有提供令牌,服务器将返回验证错误;该组件将 <Redirect> 呈现为 /login 路由;成功登录后,Login组件会隐藏令牌并重定向回来 .

  • Users组件包装器启动graphql请求并在此期间呈现"loading..." . 当graphql请求成功时,它会重新呈现并且用户会出现 .

  • 如果您从该页面退出, /logout 处的Logout组件会丢弃该令牌,然后重定向回来;用户组件's request gets the authentication error again and sends you to ' / login' .

  • 另一次成功登录后,您再次更新了're sent back to ' / users '; again it starts a graphql request to the server (and renders 591603 ), but this time, when the request succeeds, the component isn' .

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

我试图找到React正在检查组件的道具是否已经改变的地方,但我已经足够了一个React调试菜鸟,我还没弄清楚在网络检查器中哪里可以找到该代码:也许是我不喜欢的东西不了解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调试扩展行为奇怪的) .

1 回答

  • 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 - 它实际上并没有擦除整个商店,而是擦除你的商店 and 重新获取所有活动查询 . 如果你想要吹掉你的商店,因为你已经将Redux与Apollo集成在一起,最简单的方法就是create an action to do that .

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

相关问题