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

Next.js预取数据报错:TypeError: Cannot read properties of null (reading 'useState')

问题分析与修复方案

问题背景

你在Next.js项目中尝试通过自定义工具函数在getStaticProps和getStaticPaths中预取API数据时,遇到了错误:TypeError: Cannot read properties of null (reading 'useState')。相关代码如下:

1. 后端API代码

// api/projectsdata.js
export default function handler(req, res) {
  res.status(200).json([{...},{...},{...}]);
}

2. 带React Hooks的数据获取工具

import { useEffect, useState } from "react";

const ProjectsUtil = () => {
  const [data, setData] = useState(null);

  const fetchData = async () => {
    try {
      const response = await fetch("http://localhost:3000/api/projectsdata");
      const data = await response.json();

      if (response.ok) {
        setData(data);
      }
    } catch (error) {
      throw new Error(error);
    }
  };

  useEffect(() => {
    fetchData();
  }, []);

  return data !== null && data;
};

export default ProjectsUtil;

3. 数据获取辅助函数

export const getAllProjects = () => {
  const data = ProjectsUtil();
  return data;
};

export const getProjectByName = (name) => {
  const data = getAllProjects();
  return data.filter((project) => project.name === name);
};

4. 组件中的预取逻辑

const SingleProjectDetails = (props) => {
  return <ProjectDetails props={props.projectData[0]} />;
};

export function getStaticProps(context) {
  const { params } = context;
  const { id } = params;
  const projectData = getProjectByName(id);

  return {
    props: {
      projectData: projectData,
    },
    revalidate: 600,
  };
}

export function getStaticPaths() {
  const projectsData = getAllProjects();

  return {
    paths: projectsData.map((project) => ({
      params: {
        id: project.name,
      },
    })),
    fallback: true,
  };
}

错误原因

  1. React Hooks使用规则被打破:ProjectsUtil是自定义Hook(调用了useState和useEffect),自定义Hook只能在React组件顶层或其他自定义Hook中调用,不能像普通函数一样在getStaticProps/getStaticPaths这类非React渲染流程中直接执行。
  2. getStaticProps/getStaticPaths的执行环境:这两个函数在构建阶段或服务器端同步执行,不属于React组件渲染周期,完全不支持React Hooks,直接调用会抛出错误。
  3. 之前在其他组件中能正常运行,是因为你在组件顶层调用该自定义Hook,符合Hooks使用规则。

修复方案

把数据获取逻辑改成纯异步工具函数,去掉React Hooks,直接在getStaticProps/getStaticPaths中异步调用:

1. 重构数据获取工具(去掉Hooks)

// 纯异步工具函数,不依赖React Hooks
export const fetchAllProjects = async () => {
  try {
    const response = await fetch("http://localhost:3000/api/projectsdata");
    if (!response.ok) {
      throw new Error(`请求失败,状态码:${response.status}`);
    }
    return await response.json();
  } catch (error) {
    console.error("获取项目数据出错:", error);
    throw error;
  }
};

2. 重构辅助函数为异步函数

export const getAllProjects = async () => {
  return await fetchAllProjects();
};

export const getProjectByName = async (name) => {
  const allProjects = await getAllProjects();
  return allProjects.filter(project => project.name === name);
};

3. 修改getStaticProps/getStaticPaths为异步函数

const SingleProjectDetails = (props) => {
  return <ProjectDetails props={props.projectData[0]} />;
};

// 改为async函数
export async function getStaticProps(context) {
  const { params } = context;
  const { id } = params;
  const projectData = await getProjectByName(id);

  return {
    props: {
      projectData,
    },
    revalidate: 600,
  };
}

// 改为async函数
export async function getStaticPaths() {
  const projectsData = await getAllProjects();

  return {
    paths: projectsData.map(project => ({
      params: { id: project.name },
    })),
    fallback: true,
  };
}

补充说明

Next.js完全允许在getStaticProps/getStaticPaths中预取API数据,核心是要遵循这两个函数的执行规则:

  • 支持异步逻辑(用async/await)
  • 不能依赖React Hooks或浏览器端API
  • 执行环境是服务器端/构建阶段,而非浏览器客户端

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:43:19