Two instances of WebViewer were created on the same HTML element ( React App)

PDF.js Express Version

Detailed description of issue
Hi Guys, I’m trying to embed this pdf viewer in a React App, but i’m getting this error when I try to change the path of the pdf inside the useEffect(), with a dynamic variable passed through props. The initial document on the first click is getting rendered correctly, but then if I try to click on another one I have this crash. I have tried to use instance.loadDocument(lib/pdf/${filePath}) but I’m getting an error: “pdf header error”. What shall I do here? Thanks for any help I will get :slight_smile:

Expected behaviour
The pdf should change according to the filepath passed wihout any errors

Does your issue happen with every document, or just one?
Every document

Link to document

Code snippet
const App = ({filePath}) => {

const viewer = useRef(null);

useEffect(() => {

WebViewer(

  {

    path: 'lib',

    initialDoc: `lib/pdf/${filePath}`,

  },

  viewer.current

).then((instance) => {

  const { docViewer, Annotations } = instance;

  const annotManager = docViewer.getAnnotationManager();

  setInstance(instance)

       

  docViewer.on('documentLoaded', () => {

    const rectangleAnnot = new Annotations.RectangleAnnotation();

    rectangleAnnot.PageNumber = 1;

   

    rectangleAnnot.X = 100;

    rectangleAnnot.Y = 150;

    rectangleAnnot.Width = 200;

    rectangleAnnot.Height = 50;

    rectangleAnnot.Author = annotManager.getCurrentUser();

    annotManager.addAnnotation(rectangleAnnot);



    annotManager.redrawAnnotation(rectangleAnnot);

  });

});

}, [filePath]);

return (

<div className="App">

  <div className="header">React sample</div>

  <div className="webviewer" ref={viewer}></div>

</div>

);

};

export default App;

Hello, I’m Ron, an automated tech support bot :robot:

While you wait for one of our customer support representatives to get back to you, please check out some of these documentation pages:

Hey there,

You are remounting webviewer every time filePath changes which is bad practice and will make for a very slow application. I would recommend refactoring your code to something like this:

const MyComponent = () => {

  const viewer = useRef();
  const instance = useRef();

  useEffect(() => {
    WebViewer({
      path: 'lib',
      initialDoc: `lib/pdf/${filePath}`,
    }, viewer.current).then(inst => {
      instance.current = inst
    })
  }, [])

  // load the doc when filePath changes
  useEffect(() => {
    if (instance.current) {
      instance.current.loadDocument(`lib/pdf/${filePath}`)
    }
  }, [filePath])

  return (
    <div className="App">
      <div className="header">React sample</div>
      <div className="webviewer" ref={viewer}></div>
    </div>
  )
}

Thanks!
Logan

1 Like

Thank you Logan! Very appreciated :slight_smile:

1 Like