wojtekmaj / react-pdf

Display PDFs in your React app as easily as if they were images.

Home Page:https://projects.wojtekmaj.pl/react-pdf

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

onItemClick for Outline returns "Invalid pageIndex request"

hzhang20902 opened this issue · comments

Before you start - checklist

  • I followed instructions in documentation written for my React-PDF version
  • I have checked if this bug is not already reported
  • I have checked if an issue is not listed in Known issues
  • If I have a problem with PDF rendering, I checked if my PDF renders properly in PDF.js demo

Description

The Outline for PDFs will generate and will be accurate. However, no matter which link I click on, it will instantly throw this runtime error, even when no callback function is called in the onItemClick attribute:

Invalid pageIndex request.
    at WorkerTransport.getPageIndex (webpack-internal:///./node_modules/pdfjs-dist/build/pdf.js:2408:29)
    at PDFDocumentProxy.getPageIndex (webpack-internal:///./node_modules/pdfjs-dist/build/pdf.js:1223:28)
    at eval (webpack-internal:///./node_modules/react-pdf/dist/esm/OutlineItem.js:56:20)
    at Generator.next (<anonymous>)
    at fulfilled (webpack-internal:///./node_modules/react-pdf/dist/esm/OutlineItem.js:14:58)

Screenshot 2024-03-18 120514
Screenshot 2024-04-11 075240

Even when I directly copied your Recipes example into the Sample.tsx for CRA5 file, it produced this error. I also put a console.log inside that callback but it does not execute, which I'm guessing means getPageIndex is receiving a null object, one of the conditions for that error to fire off.

I also tried explicitly typing the callback function params, but still same:

function onItemClick({ pageNumber : itemPageNumber} : {pageNumber : number}) {
    console.log("THIS NUMBER? " + itemPageNumber + " this type is " + typeof(itemPageNumber))
    setPageNumber(itemPageNumber);
  }

Screenshot 2024-04-11 075419
Screenshot 2024-04-11 080209

I also copied all other Recipes directly into that file as well, and they all work, including using onItemClick as the Document attribute. But this particular circumstance of Outline using onItemClick does not work ever, EXCEPT on one PDF where the Outline generated was actually really bad and incorrect. Those links all "worked" and went to certain pages, but not really organized or aligned to the pdf's context.

Screenshot 2024-04-11 075549

Here is my component code (stripped down for easier read, there is button, input, etc):

import React, { useState, useCallback } from 'react'
import { 
  pdfjs, 
  Document, 
  Page, 
  Outline } from 'react-pdf'
import { useResizeObserver } from '@wojtekmaj/react-hooks'
import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
import 'react-pdf/dist/esm/Page/TextLayer.css';
import { VisuallyHiddenInput } from './CustomBtn';
import { Button } from '@mui/joy';
import DriveFileMoveIcon from '@mui/icons-material/DriveFileMove';

import type { PDFDocumentProxy } from 'pdfjs-dist';

pdfjs.GlobalWorkerOptions.workerSrc = new URL(
  'pdfjs-dist/build/pdf.worker.min.js',
  import.meta.url,
).toString();

//non-latin character rendering
const options = {
  cMapUrl: '/cmaps/',
  standardFontDataUrl: '/standard_fonts/',
};

const resizeObserverOptions = {};

type PDFFile = string | File | null;

function highlightPattern(text, pattern) {
  return text.replace(pattern, (value) => `<mark>${value}</mark>`);
}

export const PDFViewer = () => {
  const [file, setFile] = useState<PDFFile>('');
  const [numPages, setNumPages] = useState<number>(1);
  const [pageNumber, setPageNumber] = useState<number>(1);
  const [containerRef, setContainerRef] = useState<HTMLElement | null>(null);
  const [containerWidth, setContainerWidth] = useState<number>();
  const [searchText, setSearchText] = useState<string>('');

  const textRenderer = useCallback(
    (textItem) => highlightPattern(textItem.str, searchText),
    [searchText]
  );

  function onTextChange(event: React.ChangeEvent<HTMLInputElement>) {
    setSearchText(event.target.value);
  }

  const onResize = useCallback<ResizeObserverCallback>((entries) => {
    const [entry] = entries;

    if (entry) {
      setContainerWidth(entry.contentRect.width);
    }
  }, []);

  useResizeObserver(containerRef, resizeObserverOptions, onResize);

  function onFileChange(event: React.ChangeEvent<HTMLInputElement>): void {
    const { files } = event.target;

    if (files && files[0]) {
      setFile(files[0] || null);
    }
  }

  function onDocumentLoadSuccess({ numPages: nextNumPages }: PDFDocumentProxy): void {
    setNumPages(nextNumPages);
    setPageNumber(1);
  }

  function onItemClick({ pageNumber : itemPageNumber}) {
    console.log("THIS NUMBER? " + itemPageNumber + " this type is " + typeof(itemPageNumber))
    setPageNumber(itemPageNumber);
  }


  return (
      <div className="pdf-container">

        <div className="current-document" ref={setContainerRef}>

          <Document file={file} onLoadSuccess={onDocumentLoadSuccess} options={options} onItemClick={onItemClick}>
        
            <Outline onItemClick={onItemClick} />
           
            <Page pageNumber={pageNumber || 1} customRenderer={textRenderer} />
         
          </Document>
       </div>
    </div>
  )
}

Steps to reproduce

1. Go to Sample.tsx file in CRA sample directory, copy and paste directly into new file.

2. Got to Recipes, copy "Display Interactive Table of Contents" pieces into Sample.tsx

3. Replace the Page element with the one from Recipes.

4. Use the input to load a PDF, click on any of the Outline-populated links for the PDF.

Expected behavior

Jump to page in PDF

Actual behavior

All Outline links throw the same error:

Invalid pageIndex request.
    at WorkerTransport.getPageIndex (webpack-internal:///./node_modules/pdfjs-dist/build/pdf.js:2408:29)
    at PDFDocumentProxy.getPageIndex (webpack-internal:///./node_modules/pdfjs-dist/build/pdf.js:1223:28)
    at eval (webpack-internal:///./node_modules/react-pdf/dist/esm/OutlineItem.js:56:20)
    at Generator.next (<anonymous>)
    at fulfilled (webpack-internal:///./node_modules/react-pdf/dist/esm/OutlineItem.js:14:58)

Additional information

Please help :'(

Environment

  • Browser (if applicable): Microsoft Edge
  • React-PDF version: 7.7.1
  • React version: 18.0.0
  • Webpack version (if applicable):