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

Gatsby Build卡在静态HTML构建阶段 JSX嵌套map问题排查

问题根因

构建卡在"Building static HTML for pages" 0%进度,和JSX嵌套map遍历语法本身无关,是代码存在3个React SSR渲染逻辑问题,触发Gatsby构建时的渲染死锁:

  • 第一层items.map返回的简写Fragment <>...</> 未绑定key属性:React要求列表渲染的所有同级顶层节点必须有唯一key,简写Fragment语法不支持传入key属性,SSR阶段做虚拟DOM比对时会反复触发无效重渲染
  • 内层items2.map生成的节点key重复:当前key规则为${navKey}-${index2},该逻辑写在外层items.map循环内部,外层每一轮循环生成的内层节点key都会和上一轮完全重复,React DOM diff无法识别节点差异,会陷入无限节点重排
  • 未做items2的存在性校验:如果items2是异步加载数据、或特定页面场景下值为undefined,直接调用.map()会抛出渲染异常,Gatsby v4的SSR构建遇到未捕获的渲染错误时,部分场景不会直接打印错误日志,只会表现为进度卡死
  • 额外依赖隐患:当前项目同时安装了大版本不兼容的@emotion/core@10.x和@emotion/react@11.x,你使用的theme-ui@0.3.4原生依赖emotion 10.x版本,双版本共存会导致SSR阶段样式注入逻辑死循环,注释内层map后可以构建成功,说明核心问题为前三点,依赖冲突为次要隐患。
修复方案
  • 替换简写Fragment为支持传入key的React.Fragment,给外层循环的每个顶层节点绑定唯一key
  • 调整内层items2.map的key生成规则,拼接外层循环的index值,保证所有渲染节点key全局唯一
  • 给items2设置空数组默认值,避免值为undefined时调用map报错
  • (建议操作)移除冗余的@emotion/react依赖,保持emotion版本和theme-ui的依赖要求一致,排除双版本冲突问题

修复后的完整代码如下:

import { Fragment } from 'react'

const NaviList = ({ navKey, wrapperProps, items, items2 = [], ...props }) =>
  items ? (
    <Flex {...wrapperProps}>
      {items.map((menuItem, index) => (
        <Fragment key={`${navKey}-outer-${index}`}>
          <NaviItem {...menuItem} {...props} />
          <Box sx={styles.secondUl}>
            {items2.map((menuItem2, index2) => (
              <NaviItem 
                key={`${navKey}-${index}-inner-${index2}`} 
                {...menuItem2} 
                {...props} 
              />
            ))}
          </Box>
        </Fragment>
      ))}
    </Flex>
  ) : null
验证步骤

修改完成后先执行gatsby clean清理所有构建缓存,再执行gatsby build即可正常走完构建流程。如果仍然出现卡死问题,删除node_modules目录和依赖锁文件后重新安装依赖,彻底解决emotion双版本冲突即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:21:21