React-pdf/renderer首次加载PDF正常,关闭弹窗重开后显示整个应用如何解决?
问题原因
你遇到的问题是@react-pdf/renderer的<PDFViewer>组件复用了弹窗关闭前的旧实例,首次渲染生成的blob链接在弹窗关闭后被浏览器回收,第二次打开时实例找不到有效的PDF源,就默认加载了当前页面的完整内容,同时抛出Invalid absolute docBaseUrl警告。asm.js的报错是pdf.js的兼容性提示,不影响核心功能。
解决步骤
方案1:弹窗关闭时销毁内部内容(优先推荐)
你用的是Material UI的<Dialog>组件,默认关闭时不会卸载内部子元素,只做隐藏处理。给<Dialog>添加unmountOnExit属性,关闭弹窗时自动销毁内部的<PDFViewer>和相关实例,下次打开重新生成全新的组件树:
<Dialog aria-label="pdf-modal" className={classes.modalContent} fullScreen open={viewPDF} onClose={handlePDFClose} TransitionComponent={Transition} unmountOnExit={true} // 新增这一行 > {/* 原有内容保持不变 */} </Dialog>
方案2:强制刷新PDFViewer实例
如果加了unmountOnExit还没解决,给<PDFViewer>添加动态key,每次打开弹窗时生成新的key值,强制组件不复用旧实例:
- 先新增一个状态存key值
const [pdfViewerKey, setPdfViewerKey] = useState(0)
- 在你触发打开弹窗的逻辑里更新key
const handleOpenPDF = (invoice) => { setModalContent(invoice) setPdfViewerKey(Date.now()) // 每次打开都生成新的时间戳当key setViewPDF(true) }
- 把key绑定到PDFViewer上
<PDFViewer key={pdfViewerKey} className={classes.pdfViewer}> {/* 原有InvoicePDF保持不变 */} </PDFViewer>
方案3:手动控制blob加载(极端情况用)
如果前两个方案都不生效,放弃内置的<PDFViewer>,自己生成blob后用iframe加载,完全控制资源生命周期:
// 先从@react-pdf/renderer导出pdf方法 import { pdf } from '@react-pdf/renderer' // 打开弹窗时生成blobUrl const handleOpenPDF = async (invoice) => { const blob = await pdf( <InvoicePDF invoice={invoice} items={state.inventory} account={state.accounts?.filter(x => x.accountID === invoice.accountID)[0]} taxRate={taxRate} credits={invoiceCredits} /> ).toBlob() const blobUrl = URL.createObjectURL(blob) setPdfBlobUrl(blobUrl) setViewPDF(true) } // 关闭弹窗时释放blob资源 const handlePDFClose = () => { if (pdfBlobUrl) URL.revokeObjectURL(pdfBlobUrl) setPdfBlobUrl(null) setViewPDF(false) } // 弹窗里用iframe替代PDFViewer <Dialog {...你的原有配置} unmountOnExit={true}> {/* 原有AppBar保持不变 */} <iframe className={classes.pdfViewer} src={pdfBlobUrl} title="Invoice PDF" /> </Dialog>
内容的提问来源于stack exchange,提问作者CPUnMebb
相关产品推荐
相关产品推荐

