如何使用react-pdf库获取并展示后端返回的PDF文件,解决参数报错问题
问题原因
你触发的报错:
Invalid parameter in file, need either Uint8Array, string or a parameter object
是因为react-pdf的<Document>组件file属性不支持直接传入返回Promise的异步函数:你当前传入的() => dispatch(downloadAgreement())执行后返回的是Promise对象,不属于要求的Uint8Array、字符串、参数对象三类合法值,因此报错。
同时你当前的写法会导致每次组件渲染都重复发起PDF下载请求,额外增加性能开销,还会有内存泄漏风险。
解决方案
你需要先通过异步请求拿到PDF的可用资源值,存入state后再传给file属性,修改后代码如下:
1. 组件逻辑修改
import { useState, useEffect } from 'react'; import { Document, Page } from 'react-pdf'; // 你的业务组件 function PdfPreview() { const [pdfResource, setPdfResource] = useState(null); const [pageNumber, setPageNumber] = useState(1); useEffect(() => { // 组件挂载时发起请求拉取PDF const loadPdf = async () => { const res = await dispatch(downloadAgreement()); setPdfResource(res); }; loadPdf(); // 组件卸载时释放blob URL,避免内存泄漏 return () => { if (pdfResource?.startsWith?.('blob:')) { URL.revokeObjectURL(pdfResource); } }; }, [dispatch]); // 资源加载前展示加载态 if (!pdfResource) return <div>PDF加载中,请稍候</div>; return ( <Document file={pdfResource}> <Page pageNumber={pageNumber} /> </Document> ); }
2. 原有请求逻辑无需修改
你写的downloadAgreement逻辑本身没有问题,不需要调整。
可选优化方案
如果你不想使用blob URL,也可以直接返回Uint8Array类型的PDF资源,修改请求逻辑即可:
export const downloadAgreement = () => (dispatch) => { return axios(`https://test-zdc/pdf`, { method: 'GET', responseType: 'arraybuffer' // 响应类型修改为arraybuffer }).then((res) => { return new Uint8Array(res.data); // 直接返回Uint8Array }); };
该方案不需要处理blob URL的释放逻辑,同样可以正常运行。
内容的提问来源于stack exchange,提问作者Yerlan Yeszhanov
相关产品推荐
相关产品推荐

