首页 > 解决方案 > 为什么在使用 next/dynamic 时 Next.js 在导入时的行为与 React.js 不同?

问题描述

我正在尝试使用从“@pdftron/webviewer”导入的 WebViewer,下面标记为数字 1的代码是我在 React.js 应用程序中使用的代码,它工作正常,而代码号 2是我在 Next.js 应用程序中使用的代码引发此错误:

未处理的运行时错误类型错误:WebViewer 不是函数

代码 1(用于 React.js 应用程序):

import { useEffect, useRef } from "react";
import WebViewer from "@pdftron/webviewer";
import "./App.css";

export default function App() {
  const viewerDiv = useRef<HTMLDivElement>(null);
  useEffect(() => {
    WebViewer({ path: "./lib", initialDoc: "./sample.doc" }, viewerDiv.current as HTMLDivElement);
  }, []);
  return (
    <div>
      <div className="webviewer" ref={viewerDiv}></div>
    </div>
  );
}

代码 2(在 Next.js 应用程序中使用):

import dynamic from "next/dynamic";
const WebViewer = dynamic(() => import("@pdftron/webviewer"), { ssr: false });
import { useEffect, useRef } from "react";

export default function Editor() {
  const viewerDiv = useRef(null);
  useEffect(() => {
    WebViewer(
      {
        path: "webviewer",
        initialDoc: "http://www.africau.edu/images/default/sample.pdf",
      },
      viewerDiv.current
    );
  }, []);
  return (
    <div>
      <div className={"webviewer"} ref={viewerDiv}></div>
    </div>
  );
}

有人能解释一下为什么我在 Next.js 应用程序中出现此错误以及如何解决它吗?

更新:我也在 Next.js 应用程序中从 js 转到 ts 并收到以下警告:

'() => Promise<typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")>' 类型的参数不能分配给 'DynamicOptions | 装载机'。类型 '() => Promise<typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")>' 不可分配给类型 '() => LoaderComponent'。类型 'Promise<typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")>' 不可分配给类型 'LoaderComponent'。类型 'typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")' 不可分配给类型 'ComponentType | { 默认值:组件类型;}'。输入'typeof import(" HTMLElement) => Promise' 不可分配给类型 'ComponentType'。类型 '(options: WebViewerOptions, viewerElement: HTMLElement) => Promise' 不可分配给类型 'FunctionComponent'。“Promise”类型缺少“ReactElement<any,any>”类型的以下属性:类型、道具、键 HTMLElement) => Promise' 不可分配给类型 'ComponentType'。类型 '(options: WebViewerOptions, viewerElement: HTMLElement) => Promise' 不可分配给类型 'FunctionComponent'。“Promise”类型缺少“ReactElement<any,any>”类型的以下属性:类型、道具、键

此表达式不可调用。并非所有“ComponentType”类型的成分都是可调用的。类型 'ComponentClass<WebViewerOptions, any>' 没有调用签名。

标签: reactjsnext.js

解决方案


我设法找到了解决这个问题的方法。这是一个适合我的代码片段,如果有更好的方法,请告诉我。

import { useEffect, useRef } from "react";

export default function Editor() {
  const viewerDiv = useRef<HTMLDivElement>(null);
  const loadViewer = async () => {
    const WebViewer = (await import("@pdftron/webviewer")).default;
    WebViewer(
      {
        path: "lib",
        initialDoc: "./sample.pdf",
      },
      viewerDiv.current as HTMLDivElement
    );
  };
  useEffect(() => {
    loadViewer();
  }, []);
  return (
    <div>
      <div className={"webviewer"} ref={viewerDiv}></div>
    </div>
  );
}


推荐阅读