简体   繁体   中英

Why is Next.js acting differently than React.js at importing when using next/dynamic?

I am trying to use WebViewer imported from "@pdftron/webviewer", code below marked as number 1 is code that I use in React.js app and it works fine, while code number 2 is code that I use in Next.js app that throws this error:

Unhandled Runtime Error TypeError: WebViewer is not a function

Code number 1 (used in React.js app):

 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> ); }

Code number 2 (used in Next.js app):

 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> ); }

Can somebody explain me why am I getting this error within Next.js app and how to fix it?

UPDATE: I went from js to ts in Next.js app also and got this warnings:

Argument of type '() => Promise<typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")>' is not assignable to parameter of type 'DynamicOptions | Loader'. Type '() => Promise<typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")>' is not assignable to type '() => LoaderComponent'. Type 'Promise<typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")>' is not assignable to type 'LoaderComponent'. Type 'typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")' is not assignable to type 'ComponentType | { default: ComponentType; }'. Type 'typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")' is not assignable to type '{ default: ComponentType; }'. Types of property 'default' are incompatible. Type '(options: WebViewerOptions, viewerElement: HTMLElement) => Promise' is not assignable to type 'ComponentType'. Type '(options: WebViewerOptions, viewerElement: HTMLElement) => Promise' is not assignable to type 'FunctionComponent'. Type 'Promise' is missing the following properties from type 'ReactElement<any, any>': type, props, key

This expression is not callable. Not all constituents of type 'ComponentType' are callable. Type 'ComponentClass<WebViewerOptions, any>' has no call signatures.

I have managed to find a solution for this problem. This is a code snippet that works for me, please let me know if there is a better way.

 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> ); }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM