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

如何修复Next.js中的"TypeError: Cannot read properties of undefined (reading 'length')"错误?

Next.js问题解答

一、getStaticProps的执行时机

getStaticProps不会在Main组件渲染后执行,它是Next.js用于静态站点生成(SSG)的服务器端函数,在构建阶段(或增量静态再生时)、组件渲染前就会运行,目的是预获取数据并以props的形式传给页面组件。

注意:你把getStaticProps写在了Main组件文件中,这是错误的——Next.js只识别页面组件文件(比如pages/index.js、app/page.js)里的getStaticProps,组件文件中的该函数不会被执行,这也是你数据无法传递的核心原因。

二、TypeError报错的原因及修复

错误根源

  • 组件文件中的getStaticProps未被执行,导致Main组件接收的getposts参数为undefined;
  • 组件初始化时useState(getposts)将posts设为undefined,后续执行Math.ceil(posts.length /7)时,因为undefined没有length属性,触发报错;
  • 额外风险:getStaticProps中直接使用同步文件读取,若ContentDetail目录不存在,会直接抛出错误,进一步导致数据无法返回。

修复步骤

1. 迁移getStaticProps到页面文件

修改pages/index.js,把数据逻辑移到这里:

import Main from "../components/main/main";
import fs from 'fs';
import matter from 'gray-matter';

export async function getStaticProps() {
  // 路径基于项目根目录,确认ContentDetail位置正确
  let getposts = [];
  if (fs.existsSync('ContentDetail')) {
    const files = fs.readdirSync('ContentDetail');
    getposts = files
      .filter(fileName => fileName.endsWith('.md'))
      .map(fileName => {
        const slug = fileName.replace('.md', '');
        const fileContent = fs.readFileSync(`ContentDetail/${fileName}`, 'utf-8');
        const { data: info } = matter(fileContent);
        return { info, slug };
      });
  }

  return { props: { getposts } };
}

export default function Home({ getposts }) {
  return <Main getposts={getposts} />;
}

2. 给Main组件添加默认props

修改main.js,确保数据未传入时也不会报错:

import { useState, useRef } from 'react';

// 设置默认props,防止getposts为undefined
Main.defaultProps = {
  getposts: []
};

export default function Main({ getposts }) {
  const [posts, setPosts] = useState(getposts);
  const [groupstyle, setGroupstyle] = useState();
  const [pages, setPages] = useState([]);
  // 此时posts至少是空数组,length属性存在
  const [totalPages, setTotalPages] = useState(Math.ceil(posts.length / 7));
  const [itemOffset, setItemOffset] = useState(0);

  const currentItems = posts.slice(itemOffset, itemOffset + 7);

  const contentRef = useRef([]);
  const backRef = useRef(null);
  // 剩余业务代码...
}

额外提示

  • 确保已安装gray-matter依赖:执行npm install gray-matter或yarn add gray-matter;
  • 生产环境建议用异步文件读取(fs.promises.readdir、fs.promises.readFile),避免阻塞事件循环;
  • 若使用Next.js App Router,getStaticProps已被generateStaticParams和组件内的fetch(配置cache: 'force-cache')替代,需对应调整写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 09:57:48