我正在构建一个使用Json Web Tokens授权的应用程序 . 我'm building this application with Node.js, GraphQL and Apollo client V2 (and some other stuff, but those aren'吨在这里相关) . 我创建了一个 login
解析器和一个 currentUser
解析器,让我通过JWT获取当前用户 . 我后来使用该令牌并将其发送到我的授权 Headers 中,结果如下所示:
那部分完成了!但是这里's what I'我遇到了麻烦 .
我试图解释一下情况
我'm using React for the frontend part of this project with the Apollo Client V2. And when I do the login mutation I do it like this. With formik I' ve创建了我的 onSubmit
:
const response = await mutate({
variables: {
email: values.email,
password: values.password,
},
})
const token = response.data.login.jwt
localStorage.setItem('token', token)
history.push('/') // Navigating to the home page
这就是我想要的登录变异(只是令牌):
export const loginMutation = gql`
mutation($email: String!, $password: String!) {
login(email: $email, password: $password) {
jwt
}
}
`
为了得到 currentUser
's data I' ve,将我的 currentUser query
放入我的根路由器文件中 . Please apologize me for naming the component PrivateRoute. I haven't renamed it yet because I can't find a proper name for it. I'm sorry. 所以 /src/router/index.js
我有这个:
// First the actual query
const meQuery = gql`
{
currentUser {
id
username
email
}
}
`
...
// A component that passess the currentUser as a prop, otherwise it will be null
const PRoute = ({ component: Component, ...rest }) => {
return (
<Route
{...rest}
render={props => {
return (
<Component
{...props}
currentUser={
rest.meQuery.currentUser ? rest.meQuery.currentUser : null
}
/>
)
}}
/>
)
}
// Another component that uses the meQuery so I later can access it if I use the PrivateRoute component.
const PrivateRoute = graphql(meQuery, { name: 'meQuery' })(PRoute)
// Using the PrivateRoute. And in my Home component I can later grap the currentUser via propsb
const App = () => (
<Router>
<div>
<PrivateRoute exact path="/" component={Home} />
...
在 Home
组件中,我 grab 道具:
const { data: { loading, error, getAllPosts = [], currentUser } } = this.props
我将它传递给我的 Navbar
组件:
<Navbar currentUser={this.props.currentUser} />
在 Navbar
组件中,如果存在,我会使用用户名:
const { username } = this.props.currentUser || {}
然后我渲染它 .
这就是我遇到的麻烦
当我到达 /login
路线时,我的应用程序正在尝试获取 currentUser
. 在我成功进入后,我收回了令牌,但是 currentUser query
没有被取回 . 因此,我必须刷新页面以获取当前用户及其所有值 .
我还创建了一个小视频来演示我的问题 . 我相信它会比我尝试输入它更清楚地显示问题 .
这是视频:https://www.youtube.com/watch?v=GyI_itthtaE
我还要感谢你阅读我的帖子,希望你能帮助我 . 我不知道为什么会发生这种情况,我似乎无法解决它 . 我试着尽可能地写这个问题,很抱歉,如果这是令人困惑的阅读 .
谢谢
2 回答
我想你可以通过将查询的 FetchPolicy 设置为 "cache-and-network" 来解决这个问题 . 你可以阅读有关获取政策的信息here: "GraphQL query options.fetchPolicy"
在您的具体情况下,我认为您可以更新此行
对此:
解释
如文档中所述,默认策略是cache-first .
第一次查询
currentUser并更新缓存 .
您执行登录变异 cache is not updated 而不更新它(阅读它here: "Updating the cache after a mutation") .
currentUser查询再次执行,但由于默认的缓存优先策略,将仅从缓存中检索过期结果 .
来自official documentation:
除了这两个还有两个政策:'network-only'和'cache-only'这里是link to the documentation
对我来说,当我在登录变异中重新获取currentUser查询时,它有效 . 我在下面添加了我的代码 . 也许它有帮助: