onItemClick for Outline returns "Invalid pageIndex request"
hzhang20902 opened this issue · comments
Henry Zhang commented
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)
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);
}
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.
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):