react-pdf避免重复请求PDF文件问题求助
解决react-pdf首次加载后重复发起网络请求的问题
你的问题核心在于:组件重渲染时file对象的引用发生变化,导致Document组件重新触发PDF加载请求;同时onLoadSuccess函数每次渲染都会重新创建,也可能引发不必要的组件更新。以下是有效解决方案:
关键修复点
- 正确缓存
file对象:用useMemo缓存时,直接依赖url(而非每次渲染都会新建的对象),确保只有当url变化时才重新生成file。 - 稳定
onLoadSuccess函数引用:用useCallback包裹该函数,避免每次渲染创建新函数,减少Document组件的不必要更新。
完整修正代码
import React, { FC, useMemo, useState, useCallback } from 'react' import { Document, Page, pdfjs } from 'react-pdf' pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.js` export interface PDFProps { url: string width?: number onLoadError?: Document['props']['onLoadError'] onSuccess?: () => void } export const PDF: FC<PDFProps> = ({ url, onSuccess, onLoadError }) => { const [pageNumbers, setPageNumbers] = useState<number[]>([]) // 仅当url变化时,才重新创建file对象 const file = useMemo(() => ({ url, withCredentials: true }), [url]) // 用useCallback稳定函数引用,避免触发Document重渲染 const onLoadSuccess = useCallback<Document['props']['onLoadSuccess']>(({ numPages }) => { if (numPages !== pageNumbers.length) { const pagesIndex = [...Array(numPages).keys()].map(pageIndex => pageIndex + 1) setPageNumbers(pagesIndex) onSuccess?.() } }, [pageNumbers.length, onSuccess]) return ( <Document options={{ standardFontDataUrl: `https://unpkg.com/pdfjs-dist@${pdfjs.version}/standard_fonts`, }} file={file} onLoadSuccess={onLoadSuccess} onLoadError={onLoadError} > {pageNumbers.map(pageNumber => ( <div key={pageNumber}> <Page pageNumber={pageNumber} /> </div> ))} </Document> ) }
修复原理
useMemo依赖url而非整个对象,确保组件重渲染时file的引用保持稳定,Document不会因为file变化重新发起请求。useCallback让onLoadSuccess函数仅在pageNumbers.length或onSuccess变化时才重新创建,避免Document因函数引用变化触发不必要的更新。- 用可选链
onSuccess?.()简化了回调触发的逻辑。
内容的提问来源于stack exchange,提问作者bssyy78
相关产品推荐
相关产品推荐

