使用next-with-apollo时SSR功能失效,请求仍在客户端执行的问题排查求助
解决Next.js + next-with-apollo SSR不生效的问题
看起来你遇到的问题是SSR数据预取没触发,导致请求只能在客户端发起。我帮你分析下代码里的问题,然后给出修复方案:
核心问题:页面未触发服务端预取逻辑
Next.js的页面组件如果没有getInitialProps/getServerSideProps,服务端只会渲染空的HTML框架,不会执行组件内的数据请求逻辑。你当前的页面组件缺少这个关键钩子,导致getDataFromTree根本没机会在服务端运行。
修复步骤
1. 给页面组件添加getInitialProps
修改你的Profile页面代码,添加getInitialProps钩子,让next-with-apollo能在服务端自动调用getDataFromTree预取数据:
import gql from "graphql-tag"; import { useQuery } from "@apollo/react-hooks"; import withApollo from "../../HOC/withApollo"; const QUERY = gql` { me { user { email } } } `; const Profile = () => { const { data } = useQuery(QUERY); console.log(data); return <div>{data?.me.user?.email}</div>; }; // 添加这个钩子,触发服务端预取逻辑 Profile.getInitialProps = async () => { // 这里可以添加自定义初始化逻辑,空函数也能触发预取 return {}; }; // 不需要额外传递getDataFromTree,你的withApollo HOC已经配置正确 export default withApollo(Profile);
2. 验证配置的正确性
- 检查ApolloClient的
credentials: "include"配置:确保你的GraphQL服务端允许携带凭证(CORS配置需开启credentials支持),否则服务端发起的请求可能因权限问题失败,自动回退到客户端请求。 - 验证SSR是否生效:右键页面→查看源代码,如果能看到渲染好的用户email内容,说明预取成功;如果只有空的
<div>,说明还是客户端渲染。
可选优化:直接使用预取的数据
如果你想避免客户端重复发起请求,可以直接从props中获取服务端预取的数据:
const Profile = ({ preloadedData }) => { // 优先使用服务端预取的数据,无数据时再从缓存读取 const { data } = useQuery(QUERY, { initialData: preloadedData }); return <div>{data?.me.user?.email}</div>; }; Profile.getInitialProps = async ({ apolloClient }) => { // 手动触发数据预取,也可依赖getDataFromTree自动处理 const preloadedData = await apolloClient.query({ query: QUERY }); return { preloadedData: preloadedData.data }; };
这样修改后,服务端会在渲染页面之前完成数据请求,把数据注入到HTML中,客户端加载后直接从缓存读取,不会重复发起请求。
内容的提问来源于stack exchange,提问作者Roman Hrybinchuk
相关产品推荐
相关产品推荐

