You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 06:47:48