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
相关产品推荐
相关产品推荐

