Next.js+TS构建静态页时报Array is not iterable错误
Next.js构建阶段「Array is not iterable」错误修复
问题现象
使用TypeScript开发Next.js应用时,开发环境开启严格类型检查无任何报错,自定义Accordion组件接收accordion对象数组props时运行正常,但执行生产构建的静态页面生成环节时,抛出Array is not iterable错误。
相关组件代码如下:
import React from 'react' import Link from 'next/link' import { nanoid } from 'nanoid' import { NextPage } from 'next' interface Section { header: string prompt: string linkRef: string linkTxt: string bs: string id: string } type Props = { accordion: Section[] children: any[] } const Accordion: NextPage<Props> = ({ accordion, children }) => { const [firstItem, ...otherItems] = accordion console.log(accordion) const others = otherItems.map((i: Section, index: number) => ( <div key={nanoid()} className="accordion-item"> <h2 className="accordion-header" id={`heading${i.bs}`}> <button className="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target={`#collapse${i.bs}`} aria-expanded="true" aria-controls={`collapse${i.bs}`} > {i.header} → </button> </h2> <div id={`collapse${i.bs}`} className="accordion-collapse collapse" aria-labelledby={`heading${i.bs}`} data-bs-parent="#main" > <section id={i.id} className="accordion-body"> <div>{children[index + 1]}</div> <div> {i.prompt} <Link href={i.linkRef}> <a>{i.linkTxt}</a> </Link> </div> </section> </div> </div> )) return ( <div key={nanoid()} className="accordion" id="main"> <div className="accordion-item"> <h2 className="accordion-header" id="headingOne"> <button className="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne" > {firstItem.header} → </button> </h2> <div id="collapseOne" className="accordion-collapse collapse" aria-labelledby="headingOne" data-bs-parent="#main" > <section id={firstItem.id} className="accordion-body"> <div className="mdxContainer">{children[0]}</div> <div> {firstItem.prompt} <Link href={firstItem.linkRef}> <a>{firstItem.linkTxt}</a> </Link> </div> </section> </div> </div> {others} </div> ) } export default Accordion
已排查到的现象:
- 开发环境运行完全正常,TS无类型报错
- 报错仅出现在生产构建的静态生成阶段
- 运行时日志打印
accordion为数组类型,Array.isArray(accordion)返回true
根因分析
- 错误的组件类型标注是核心诱因:
NextPage类型是Next.js为pages/目录下的路由页面组件专门设计的类型,构建阶段Next.js会对所有标记为NextPage的组件执行特殊的页面级props注入逻辑。在静态生成的首次预渲染 pass 中,框架会优先尝试读取页面级静态props(getStaticProps/getServerSideProps返回值),你手动传入的accordionprops在这一步会被覆盖为undefined,执行数组解构时直接抛出不可迭代错误。 - 日志偏差导致排查方向错误:你看到的
accordion为数组的日志,都是客户端hydration完成后的运行时打印,构建报错发生在服务端预渲染的最早阶段,代码还没执行到console.log就已经抛出错误中断构建,所以你看不到这次失败渲染的实际入参。 - 缺少容错逻辑放大问题:组件没有给数组类型props设置兜底默认值,TS静态类型检查无法覆盖构建阶段框架动态注入props的场景,一旦入参不符合预期就直接触发运行时错误。
修复步骤
按以下顺序修改即可解决构建报错:
- 移除错误的
NextPage类型标注:普通可复用UI组件不要使用NextPage类型,直接标注props类型即可,同时删掉无用的NextPage导入。 - 给所有数组类型props添加空数组默认值,从根源避免解构时拿到非可迭代值:
// 修改后的组件签名 const Accordion = ({ accordion = [], children = [] }: Props) => { // 原有业务逻辑保持不变 } - 修正children类型定义:React children不永远是数组,单个子节点时为单个React元素,无传入时为undefined,将Props里的children类型从
any[]改为内置的React.ReactNode,避免后续出现类型和运行时不匹配的问题。 - (可选优化)移除渲染时随机生成key的逻辑:不要在map循环和组件根节点调用
nanoid()生成key,服务端渲染和客户端hydration时生成的随机id不一致会触发hydration mismatch警告,直接使用每个Section自带的唯一id字段作为key即可,组件根节点不需要额外加key。
内容的提问来源于stack exchange,提问作者Ryan Gregory
相关产品推荐
相关产品推荐

