React中跨页面传递PDF文件的解决方案咨询
跨页面传递PDF文件的可行方案
针对你在React Router应用中跨页面传递PDF文件的需求,以下是几种绕过Redux/Context序列化限制的方案:
1. 利用React Router的路由state传递
路由跳转时可以通过state携带非序列化数据(如File对象),适合临时传递(页面刷新后数据会丢失,若需要持久化不推荐)。
实现步骤:
- 在Home页面,使用
useNavigate跳转时传入文件到state:
// Home.jsx import { useNavigate } from 'react-router-dom'; function Home() { const navigate = useNavigate(); const handleFileUpload = (e) => { const file = e.target.files[0]; if (file && file.type === 'application/pdf') { // 跳转到Analyser页面并携带文件 navigate('/Analyser', { state: { pdfFile: file } }); } }; return ( <div> <input type="file" accept="application/pdf" onChange={handleFileUpload} /> </div> ); }
- 在Analyser页面,使用
useLocation获取state中的文件:
// Analyser.jsx import { useLocation } from 'react-router-dom'; import { Document, Page } from 'react-pdf'; // 示例用react-pdf预览 function Analyser() { const location = useLocation(); const pdfFile = location.state?.pdfFile; return ( <div> {pdfFile && ( <Document file={pdfFile}> <Page pageNumber={1} /> </Document> )} </div> ); }
2. 将PDF转为Base64字符串存储
把File对象转为Base64字符串(序列化数据),可以存在localStorage、sessionStorage甚至Redux/Context中,适合需要持久化的场景(注意大文件会导致Base64体积膨胀,可能超出存储限制)。
实现步骤:
- Home页面转Base64并存储:
// Home.jsx import { useNavigate } from 'react-router-dom'; function Home() { const navigate = useNavigate(); const handleFileUpload = (e) => { const file = e.target.files[0]; if (file && file.type === 'application/pdf') { const reader = new FileReader(); reader.onload = (event) => { const base64Pdf = event.target.result; // 存到sessionStorage sessionStorage.setItem('pdfBase64', base64Pdf); navigate('/Analyser'); }; reader.readAsDataURL(file); } }; return ( <div> <input type="file" accept="application/pdf" onChange={handleFileUpload} /> </div> ); }
- Analyser页面读取并预览:
// Analyser.jsx import { useEffect, useState } from 'react'; import { Document, Page } from 'react-pdf'; function Analyser() { const [pdfBase64, setPdfBase64] = useState(null); useEffect(() => { const base64 = sessionStorage.getItem('pdfBase64'); if (base64) { setPdfBase64(base64); // 用完可以移除,避免占用存储 sessionStorage.removeItem('pdfBase64'); } }, []); return ( <div> {pdfBase64 && ( <Document file={pdfBase64}> <Page pageNumber={1} /> </Document> )} </div> ); }
3. 生成Blob URL传递
通过URL.createObjectURL生成临时的Blob URL,将URL传递给目标页面,预览完成后记得释放URL避免内存泄漏。
实现步骤:
- Home页面生成Blob URL并跳转:
// Home.jsx import { useNavigate } from 'react-router-dom'; function Home() { const navigate = useNavigate(); const handleFileUpload = (e) => { const file = e.target.files[0]; if (file && file.type === 'application/pdf') { const blobUrl = URL.createObjectURL(file); // 可以存到sessionStorage或者通过路由state传递 sessionStorage.setItem('pdfBlobUrl', blobUrl); navigate('/Analyser'); } }; return ( <div> <input type="file" accept="application/pdf" onChange={handleFileUpload} /> </div> ); }
- Analyser页面使用并释放URL:
// Analyser.jsx import { useEffect, useState } from 'react'; import { Document, Page } from 'react-pdf'; function Analyser() { const [pdfBlobUrl, setPdfBlobUrl] = useState(null); useEffect(() => { const url = sessionStorage.getItem('pdfBlobUrl'); if (url) { setPdfBlobUrl(url); } // 组件卸载时释放URL return () => { if (pdfBlobUrl) { URL.revokeObjectURL(pdfBlobUrl); sessionStorage.removeItem('pdfBlobUrl'); } }; }, [pdfBlobUrl]); return ( <div> {pdfBlobUrl && ( <Document file={pdfBlobUrl}> <Page pageNumber={1} /> </Document> )} </div> ); }
4. 提升状态到父组件(App.jsx)
将文件状态提升到App组件,通过props传递给子页面(无需持久化,避免序列化问题)。
修改App.jsx:
import React, { useState } from 'react'; import { BrowserRouter as Router, Route, Routes, } from 'react-router-dom'; import './App.css'; import Loader from './Components/Loading/Loading'; const Home = React.lazy(() => import('./Pages/Home/Home')); const Analyser = React.lazy(() => import('./Pages/ContractAnalyser/Analyser')); function App() { const [pdfFile, setPdfFile] = useState(null); return ( <div className="main"> <Router> <Routes> <Route path="/" element={( <React.Suspense fallback={<Loader />}> <Home setPdfFile={setPdfFile} /> </React.Suspense> )} /> <Route path="/Analyser" element={( <React.Suspense fallback={<Loader />}> <Analyser pdfFile={pdfFile} /> </React.Suspense> )} /> </Routes> </Router> </div> ); } export default App;
Home页面设置状态:
// Home.jsx import { useNavigate } from 'react-router-dom'; function Home({ setPdfFile }) { const navigate = useNavigate(); const handleFileUpload = (e) => { const file = e.target.files[0]; if (file && file.type === 'application/pdf') { setPdfFile(file); navigate('/Analyser'); } }; return ( <div> <input type="file" accept="application/pdf" onChange={handleFileUpload} /> </div> ); }
Analyser页面使用状态:
// Analyser.jsx import { Document, Page } from 'react-pdf'; function Analyser({ pdfFile }) { return ( <div> {pdfFile && ( <Document file={pdfFile}> <Page pageNumber={1} /> </Document> )} </div> ); }
内容的提问来源于stack exchange,提问作者Spidy
相关产品推荐
相关产品推荐

