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

使用Next.js时出现TypeError: Cannot read property 'useState' of null如何解决?

修复Next.js中useState触发"TypeError: Cannot read property 'useState' of null"错误

错误信息

TypeError: Cannot read property 'useState' of null

出错代码

import { useState } from "react";
import { getLimitedTutors } from "utils/api/tutors"; 

const [tutorLimit, setTutorLimit] = useState(10); // 错误发生位置

export async function getStaticProps() {
  const { data: tutor } = await getLimitedTutors(tutorLimit ? tutorLimit : 10);
  return {
    props: {
      tutors: tutor.data,
    },
  };
}

// 导出组件部分

getLimitedTutors 实现代码

export function getLimitedTutors(limit) {
  return cms.get(`/tutors?pagination[start]=0&pagination[limit]=${limit}&populate=*`);
}

问题原因

  1. useState调用位置违规:React Hook(包括useState)必须在React组件的顶层作用域内调用,不能在组件外部、服务端函数(如getStaticProps)或非组件逻辑中使用,你直接在模块顶层声明useState,违反了Hook的使用规则。
  2. 跨作用域变量引用错误:getStaticProps是Next.js在构建/服务端阶段运行的函数,和客户端组件渲染完全隔离,根本无法访问组件的状态变量tutorLimit。

修复方案

方案1:将useState移至组件内部

把状态声明放到导出的React组件内部,getStaticProps中使用固定值初始化数据:

import { useState } from "react";
import { getLimitedTutors } from "utils/api/tutors"; 

// 构建时获取初始数据
export async function getStaticProps() {
  const { data: tutor } = await getLimitedTutors(10);
  return {
    props: {
      tutors: tutor.data,
    },
  };
}

// React组件内部使用useState
export default function TutorsPage({ tutors }) {
  const [tutorLimit, setTutorLimit] = useState(10);

  // 组件渲染逻辑
  return (
    <div>
      {/* 你的组件内容 */}
    </div>
  );
}

方案2:前端动态调整显示数量(推荐)

如果需要通过前端交互切换导师显示数量,可在组件内部对初始获取的数据做过滤,避免重复请求:

import { useState } from "react";
import { getLimitedTutors } from "utils/api/tutors"; 

// 构建时获取足够多的初始数据
export async function getStaticProps() {
  const { data: tutor } = await getLimitedTutors(20);
  return {
    props: {
      allTutors: tutor.data,
    },
  };
}

export default function TutorsPage({ allTutors }) {
  const [tutorLimit, setTutorLimit] = useState(10);
  // 根据状态过滤显示的数据
  const displayedTutors = allTutors.slice(0, tutorLimit);

  return (
    <div>
      <button onClick={() => setTutorLimit(prev => prev + 5)}>加载更多</button>
      {displayedTutors.map(tutor => (
        <div key={tutor.id}>{tutor.attributes.name}</div>
      ))}
    </div>
  );
}

方案3:动态请求不同数量的数据(用SWR)

如果必须根据前端状态动态请求不同数量的数据,使用SWR实现客户端数据请求:

import { useState } from "react";
import useSWR from 'swr';
import { getLimitedTutors } from "utils/api/tutors"; 

// 自定义请求函数
const fetcher = (limit) => getLimitedTutors(limit).then(res => res.data);

export default function TutorsPage() {
  const [tutorLimit, setTutorLimit] = useState(10);
  // 根据tutorLimit动态请求数据
  const { data, error } = useSWR(tutorLimit, fetcher);

  if (error) return <div>加载失败</div>;
  if (!data) return <div>加载中...</div>;

  return (
    <div>
      <button onClick={() => setTutorLimit(prev => prev + 5)}>加载更多</button>
      {data.data.map(tutor => (
        <div key={tutor.id}>{tutor.attributes.name}</div>
      ))}
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 22:50:28