我正在构建一个基于graphql的身份验证机制,我正在试图弄清楚为什么一个graphql连接的组件在重新登录后没有重新渲染...例如:
/users
我有一个react-apollo graphql-connected用户组件,用于请求用户列表。<Redirect>
路由呈现/login
;成功登录后,Login组件会存储令牌并重定向回来。/logout
处的Logout组件会丢弃该令牌,然后重定向回来; Users组件的请求再次获得身份验证错误,并将您发送到'/ login'。我可以看到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调试扩展行为很奇怪)。
答案 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。
您可能还需要考虑基于会话的身份验证机制,而不是依赖客户端来持久化令牌。实现服务器端非常简单,不仅需要在客户端执行较少的工作(不必记住在每个请求中传递令牌),并且会让您保留用户他们离开页面后登录。