我正在构建一个基于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 回答
要解决此问题,请修改graphql HOC以在选项中包含
notifyOnNetworkStatusChange
.我不认为你应该这样做 - 我认为
data.loading
应该准确反映你的查询的状态,无论该选项被设置为true,不像data.networkStatus
但它looks like it's a known bug .至于
resetStore
- 它实际上并没有擦除整个商店,而是擦除你的商店 and 重新获取所有活动查询 . 如果你想要吹掉你的商店,因为你已经将Redux与Apollo集成在一起,最简单的方法就是create an action to do that .您可能还需要考虑基于会话的身份验证机制,而不是依赖客户端来持久化令牌 . 实现服务器端非常简单,不仅会减少客户端的工作量(不必记住在每个请求中都传递令牌),并且可以让用户在导航后保持用户登录从页面 .