如何在Next.js App目录的服务端组件中发起Apollo GraphQL请求?
如何在Next.js的App Router服务端组件中发起GraphQL请求?
遇到的问题
在App Router的app/page.tsx中使用getServerSideProps时,出现编译错误:
Failed to compile
× "getServerSideProps" is not supported in app/.
对应的app/page.tsx代码:
import { client } from "@/GraphQL/apollo-client"; import { fetchJobs } from "@/GraphQL/queries"; import Jobs from "@/components/jobs"; import React from "react"; export async function getServerSideProps() { const { data } = await client.query({ query: fetchJobs }); const jobs = data?.jobs || []; return { props: { jobs } }; } const page = ({ jobs }) => { console.log(jobs); return ( <div> <Jobs jobs={jobs} /> </div> ); }; export default page;
components/jobs.tsx代码:
import React from "react"; import { client } from "@/GraphQL/apollo-client"; import { fetchJobs } from "@/GraphQL/queries"; import { useSuspenseQuery } from "@apollo/client"; const Jobs = ({ jobs }) => { console.log({ jobs }); return <div>jobs</div>; }; export default Jobs;
尝试过的无效方案
创建Pages Router页面:在根目录创建
pages/jobs/index.js,但访问/jobs时出现404错误import { client } from "@/GraphQL/apollo-client"; import { fetchJobs } from "@/GraphQL/queries"; const Test = () => { return <div>page</div>; }; export default Test; export async function getServerSideProps() { const { data } = await client.query({ query: fetchJobs, }); console.log("HEY", data); return { props: { data, }, }; }在组件中添加getServerSideProps:在
Jobs组件内定义getServerSideProps,但函数未执行,也没有打印日志const Jobs = () => { return <div>jobs</div>; }; export default Jobs; export async function getServerSideProps() { const { data } = await client.query({ query: fetchJobs }); const jobs = data?.jobs || []; console.log("first"); return { props: { jobs } }; }
正确解决方案
方案1:App Router服务端组件直接异步请求
App Router的组件默认是服务端组件,可以直接在组件函数中编写异步代码获取数据,无需getServerSideProps:
修改app/page.tsx:
import { client } from "@/GraphQL/apollo-client"; import { fetchJobs } from "@/GraphQL/queries"; import Jobs from "@/components/jobs"; import React from "react"; // 组件函数改为异步 const Page = async () => { const { data } = await client.query({ query: fetchJobs }); const jobs = data?.jobs || []; console.log(jobs); return ( <div> <Jobs jobs={jobs} /> </div> ); }; export default Page;
components/jobs.tsx可以简化(不需要多余的导入):
import React from "react"; const Jobs = ({ jobs }) => { console.log({ jobs }); return <div>jobs</div>; }; export default Jobs;
方案2:使用Pages Router(保留getServerSideProps)
如果要继续用getServerSideProps,需要注意:
getServerSideProps只能在Pages Router的页面文件(pages目录下的文件)中使用,不能在组件文件中定义- 确保项目未禁用Pages Router:如果同时存在
app和pages目录,Next.js会同时支持两者,访问pages/jobs/index.js的路径是/jobs - 文件名要匹配:如果是TypeScript项目,建议用
index.tsx而非index.js,避免类型错误
补充说明
- App Router中,未添加
'use client'指令的组件默认是服务端组件,支持直接执行异步逻辑 - 如果需要在客户端组件中请求数据,需添加
'use client'指令,然后使用Apollo的useQuery或useSuspenseQuery钩子
内容的提问来源于stack exchange,提问作者Gagan
相关产品推荐
相关产品推荐

