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

如何将Context API获取的数据传递给getServerSideProps函数?

问题:无法在getServerSideProps中使用Context API获取数据

遇到错误:

React Hook "useContext" is called in function "getServerSideProps" that is neither a React function component nor a custom React Hook function

我的场景是:用Context API在客户端获取数据,想把这些数据传递给getServerSideProps,同时不想在Home组件里直接使用Context,也不想重复写请求代码。


现有代码

AppContext.tsx:

export const AppContext = createContext(null);
export const AppContextProvider = ({ children }) => {
  const [data, setData] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch('http://localhost:8080/api/users');
      const body = await response.json();
      setData(body.users);
    };
    fetchData();
  }, []);
  return (
    <AppContext.Provider value={data}>{children}</AppContext.Provider>
  );
};

index.tsx(路径:apps/ui/pages/index.tsx):

const Home: NextPage<HomeProps> = ({ tiers }) => {
  const data = useAppContext();
  console.log('data', data); // 此处能正常打印数据

  return (
    <Box>
      <Head>
        <title>React App</title>
      </Head>
      {data?.map((user) => (
        // 渲染用户内容
      ))}
    </Box>
  );
};

export async function getServerSideProps() {
  // const data = useContext(AppContext); // 此处触发上述错误
  return {
    props: {
      data,
    },
  };
}

export default Home;

临时方案是在index.tsx里重复写请求逻辑,但不想这么做,希望复用Context里的请求逻辑。


问题原因

  1. getServerSideProps是Next.js的服务器端专属函数,不属于React组件或自定义Hook,完全不遵循React Hook的调用规则,因此不能调用useContext这类Hook。
  2. Context是React客户端渲染周期内的状态容器,服务器端执行getServerSideProps时,客户端的Context实例还未创建,根本无法访问到Context中的数据。

正确解决方案:抽离复用请求逻辑

把数据请求的核心逻辑抽成独立函数,同时在AppContextProvider和getServerSideProps中复用这个函数,既避免重复代码,又符合Next.js和React的规则。

步骤1:抽离请求函数

创建一个独立的工具文件(比如utils/api.ts),或者直接在AppContext.tsx中导出:

// utils/api.ts
export const fetchUsers = async () => {
  const response = await fetch('http://localhost:8080/api/users');
  const body = await response.json();
  return body.users;
};

步骤2:修改AppContext.tsx,复用请求函数

import { createContext, useState, useEffect } from 'react';
import { fetchUsers } from './utils/api';

export const AppContext = createContext(null);
export const AppContextProvider = ({ children }) => {
  const [data, setData] = useState([]);

  useEffect(() => {
    const loadData = async () => {
      const users = await fetchUsers();
      setData(users);
    };
    loadData();
  }, []);

  return (
    <AppContext.Provider value={data}>{children}</AppContext.Provider>
  );
};

步骤3:修改index.tsx,在getServerSideProps中复用请求函数

import { NextPage } from 'next';
import { Box, Head } from '@mui/material';
import { fetchUsers } from '../utils/api';

type HomeProps = {
  data: User[]; // 定义你的User类型
};

const Home: NextPage<HomeProps> = ({ data }) => {
  // 直接使用props传递的数据,无需useContext
  return (
    <Box>
      <Head>
        <title>React App</title>
      </Head>
      {data?.map((user) => (
        <div key={user.id}>{user.name}</div>
      ))}
    </Box>
  );
};

export async function getServerSideProps() {
  const data = await fetchUsers();
  return {
    props: {
      data,
    },
  };
}

export default Home;

方案说明

  • 服务器端:getServerSideProps提前获取数据,通过props传递给Home组件,支持服务端渲染。
  • 客户端:如果用户是通过客户端导航进入该页面(比如从其他页面跳转),getServerSideProps不会执行,此时AppContextProvider中的useEffect会调用复用的请求函数获取数据,保证客户端也能拿到数据。
  • 完全避免了重复写请求代码,同时符合Next.js和React的运行规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 03:30:40