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

React中PDF渲染报错:更新深度超出最大值问题求助

解决React渲染多个PDF时的无限更新循环错误

问题根源

你用全局的numPagesState状态存储所有PDF的页数,每个<Document>组件加载成功后都会调用setNumPagesState更新状态——这会触发整个父组件重新渲染,重新渲染后所有<Document>又会再次执行onLoadSuccess,形成无限循环,最终触发Maximum update depth exceeded错误。同时多个PDF共享同一个页数状态,还会导致所有PDF显示最后加载完成的那个文件的页数,显示逻辑混乱。

解决方案

把单个证书的渲染逻辑抽成独立子组件,让每个证书自己维护专属的页数状态,避免全局状态冲突和循环更新。

修改后的代码示例

首先创建单个证书的子组件:

const CertificatePreview = ({ el, setSelectedPreview, setOpenCertificateModal, setDeleteCertificateModal, width }) => {
  // 每个证书独立维护页数状态
  const [numPages, setNumPages] = useState(0);

  return (
    <div>
      <div className="d-flex justify-content-between edit-delete-section">
        <div className="course-completion">
          Course Completion Certificate
        </div>
        <div className="d-flex">
          <div
            onClick={() => {
              setSelectedPreview(el);
              setOpenCertificateModal(true);
            }}
          >
            <Edit className="EditIcon cursor-pointer" />
          </div>
          <div
            onClick={() => {
              setDeleteCertificateModal(true);
            }}
          >
            <Delete className="delete-button cursor-pointer" />
          </div>
        </div>
      </div>

      <div className="document-preview-form">
        <Document
          file={el?.file_url || "/blank.pdf"}
          onLoadSuccess={({ numPages }) => setNumPages(numPages ?? 0)}
        >
          {Array.from({ length: numPages }, (_, i) => i + 1).map((page) => (
            <Page
              key={page}
              width={width || 1}
              pageNumber={page}
            />
          ))}
        </Document>
      </div>
    </div>
  );
};

然后在原组件中调用这个子组件:

const allCertificates = formik?.values?.certificate_file || [];

{allCertificates.length > 0 &&
  allCertificates.map((el, index) => (
    <CertificatePreview
      key={el.id || index} // 优先用数据的唯一标识,无则用index
      el={el}
      setSelectedPreview={setSelectedPreview}
      setOpenCertificateModal={setOpenCertificateModal}
      setDeleteCertificateModal={setDeleteCertificateModal}
      width={width}
    />
  ))}

关键说明

  • 每个子组件独立管理numPages状态,更新时仅触发自身重渲染,不会引发全局循环。
  • 给map循环的元素添加唯一key,确保React正确识别列表项,避免不必要的重渲染。
  • 用Array.from替代Array.apply生成页码数组,代码更简洁可读。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 06:43:11