如何修复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
相关产品推荐
相关产品推荐

