You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中如何在getServerSideProps内执行graphql-codegen生成的mutation

报错核心原因

useGetTokenMutation是Apollo配合React生成的Hook函数,只能在React函数组件、自定义Hook的顶层作用域内调用。而getServerSideProps是Next.js在服务端独立运行的普通异步函数,完全不在React组件的渲染上下文里,在这里直接调用Hook必然触发React的Hook规则校验报错。

你提到的graphql-codegen-apollo-next-ssr插件不生成Mutation的服务端适配代码不是配置错误,这个插件本身的设计定位就是给SSR阶段的读操作(Query)生成预取代码,Mutation作为带写副作用的操作,从设计之初就没被纳入插件的SSR适配范围。

正确实现方式

不需要等插件支持Mutation的SSR适配,直接在getServerSideProps中通过Apollo Client实例手动调用mutation即可,逻辑非常直接:

  • 准备好可在服务端运行的Apollo Client实例,注意不要用依赖浏览器API(比如window、document)的客户端实例,同时要保证不同用户请求之间的实例状态隔离,避免数据串扰。
  • 在getServerSideProps中拿到实例后,直接调用实例自带的mutate方法,传入codegen生成的Mutation文档节点和对应变量即可,完全不需要使用Hook。

参考实现代码:

// 导入codegen生成的Mutation文档,和你组件里useGetTokenMutation依赖的是同一份gql定义
import { GetTokenDocument } from '@/generated/graphql';
// 导入你项目中封装好的服务端Apollo Client初始化方法
import { initServerApolloClient } from '@/lib/apollo/server';

export async function getServerSideProps(context) {
  // 基于当前请求上下文初始化服务端Apollo Client
  const client = initServerApolloClient({
    req: context.req,
    res: context.res
  });

  // 直接执行mutation,传参逻辑和组件里调用getTokenMutation完全一致
  const mutationResult = await client.mutate({
    mutation: GetTokenDocument,
    variables: {
      // 填入你需要传的参数,比如从context里拿到的code、认证信息等
    }
  });

  const token = mutationResult.data?.getToken;

  // 后续业务逻辑,比如把token注入页面props、做重定向、权限校验等
  return {
    props: {
      token
    }
  };
}
注意事项
  • 不要把有明确用户交互触发的写操作(比如提交表单、下单、修改用户资料)放到getServerSideProps里执行。getServerSideProps会在每次页面请求时自动运行,放这类操作很容易出现非预期的重复触发。如果是获取服务端token、校验接口权限这类无用户感知的副作用操作,放在这里执行是没问题的。
  • 如果你用的是其他GraphQL客户端(比如urql、graphql-request),核心逻辑完全一致:不要调用React Hook封装的方法,直接导入服务端可用的客户端实例,调用实例的mutation执行方法,传入对应请求文档和参数即可。
  • 服务端使用的Apollo Client不要做成全局单例存储用户态数据(比如认证token、用户个性化缓存),否则会出现不同用户请求之间的数据泄露问题。

内容的提问来源于stack exchange,提问作者sev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 18:36:51