Next.js+React-Apollo认证问题:当前用户查询返回null,刷新后正常
解决React-Apollo + Next.js认证后当前用户查询返回null的问题
嘿,这个问题我之前在项目里也踩过坑!核心原因其实是:当你提交凭证成功拿到JWT Cookie后,Apollo Client的缓存还没同步更新当前用户的查询结果——组件里的初始查询是在认证完成前发起的,所以拿到的是null;而刷新页面后,Next.js重新初始化Apollo Client,带着新的Cookie请求后端,自然就能拿到正确的用户数据了。
下面给你几个亲测有效的解决方案:
1. 登录成功后手动更新Apollo缓存
在登录的Mutation执行完成后,直接把返回的用户数据写入Apollo的缓存,这样组件就能立刻读到最新数据,不用刷新页面。
假设你的当前用户查询是GET_CURRENT_USER,登录Mutation返回了用户信息,代码可以这么写:
import { gql } from '@apollo/client'; // 定义当前用户查询 const GET_CURRENT_USER = gql` query GetCurrentUser { currentUser { id name email } } `; // 你的登录处理逻辑 handleLogin = async (credentials) => { const { client } = this.props; try { const { data } = await client.mutate({ mutation: LOGIN_MUTATION, // 你的登录Mutation variables: { credentials } }); // 手动将用户数据写入缓存 client.writeQuery({ query: GET_CURRENT_USER, data: { currentUser: data.login.user } // 对应你Mutation返回的用户字段 }); } catch (error) { console.error('登录失败:', error); } };
2. 使用Mutation的refetchQueries自动重新查询
另一种更省心的方式是,在登录Mutation的配置里加上refetchQueries选项,指定要重新执行的当前用户查询。这样Mutation成功后,Apollo会自动重新发起查询,更新组件数据和缓存。
handleLogin = async (credentials) => { const { client } = this.props; try { await client.mutate({ mutation: LOGIN_MUTATION, variables: { credentials }, // 指定要重新获取的查询 refetchQueries: [{ query: GET_CURRENT_USER }] }); } catch (error) { console.error('登录失败:', error); } };
3. 检查Next.js的服务端渲染逻辑
如果你的Index组件用了getInitialProps或者服务端渲染(SSR),要注意:登录是客户端操作,服务端渲染时Cookie还没设置,所以服务端返回的currentUser是null,客户端接管后也不会自动重新查询。这时候可以在组件挂载后手动触发查询:
componentDidMount() { // 组件挂载后重新查询当前用户 this.props.client.query({ query: GET_CURRENT_USER }) .catch(error => console.error('重新查询用户失败:', error)); }
这样即使服务端返回的是null,客户端挂载后会重新请求,拿到最新的用户数据。
内容的提问来源于stack exchange,提问作者Ross Baquir
相关产品推荐
相关产品推荐

