PDFtron & react 错误:在同一个 HTML 元素上创建了两个 WebViewer 实例请为每个 WebViewer 实例创建一个新元素

问题描述

我试图在应用程序中显示我使用 PDFtron 在 React 中构建的 PDF 文件,但遇到以下错误:在同一个 HTML 元素上创建了两个 WebViewer 实例。请为每个 WebViewer 实例创建一个新元素。

我的代码是:

import { url } from "../../../../config.json";
import React,{ useState,useEffect,useRef } from "react";
import { getProject } from "../../../../services/projectService";
import { useParams } from "react-router-dom";
import WebViewer from "@pdftron/webviewer";
import { getCurrentUser } from "../../../../services/userService";
import { Link,Redirect } from "react-router-dom";
import { deleteImage } from "../../../../services/projectService";

const MyContracts = () => {
const [project,setProject] = useState({});
const [counter,setCounter] = useState(0);
const [files,setFiles] = useState([]);
const { id } = useParams();
// const viewerDiv = useRef();
const user = getCurrentUser();
const [viewerUrl,setViewerUrl] = useState(`${url}/files/testing.pdf`);
const viewer = document.getElementById("viewer");
    
useEffect(() => {
getProject(id)
.then(res => {
setProject(res.data);
setFiles(res.data.files.contracts);
})
.catch(error => console.log(error.message));
},[]);
    
useEffect(() => {
if (files.length > 0) {
WebViewer(
{
path: `${url}/lib`,initialDoc: `${url}/files/testing.pdf`,fullAPI: true,},viewer
).then(async instance => {
const { docViewer } = instance;
docViewer.getDocument(viewerUrl);
});
}
},[files,viewerUrl]);
if (!user) return <Redirect to="/private-area/sign-in" />;
if (user && user.isAdmin | (user._id === project.userID))
return (
<div className="container">
</div>
{/********** PDF VIEWER ************/}
<div className="web-viewer" id="viewer"></div>
{/* <div className="web-viewer" ref={viewerDiv} id="viewer"></div> */}
    
{/********** PDF gallery ************/}
{files !== undefined && (
<>
<h2 className="text-rtl h3Title mt-2">בחר קובץ</h2>
<select
id="select"
className="col-12 text-rtl px-0"
onChange={e => setViewerUrl(e.target.value)}>
{files.map((file,index) => (
<option value={`${url}${file.url}`} key={index}>
{file.name}
</option>
))}
</select>
</>
)}
</div>
);
};
    
export default MyContracts;

我做错了什么,我该如何解决

解决方法

我看到您正在尝试加载多个 WebViewer 实例:

useEffect(() => {
        if (files.length > 0) {
            WebViewer(
                {
                    path: `${url}/lib`,initialDoc: `${url}/files/testing.pdf`,fullAPI: true,},viewer
            ).then(async instance => {
                const { docViewer } = instance;
                docViewer.getDocument(viewerUrl);
            });
        }
    },[files,viewerUrl]);

不能在同一个 HTML 元素中多次实例化 Webviewer。如果您需要一个完全不同的实例,您可以隐藏或删除 HTML 元素并创建一个新元素来保存新实例。

话虽如此,如果您只需要加载另一个文档,我建议使用 loadDocument API (https://www.pdftron.com/api/web/WebViewerInstance.html#loadDocument__anchor)。您也可以在此处https://www.pdftron.com/documentation/web/guides/basics/open/load-options/阅读更多相关信息。