4

So far, using react-pdf has been simple, but I'm missing a crucial piece that I don't know how to find. I'm trying to get the total number of pages of a PDF document on load. I need this to create a page number navigation. Clearly the data exists somewhere, because changing the <Page> tag's pageNumber prop to a hard coded value will display the proper page. But I have no idea how to access it.

My code is below. As far as I can tell, I'm doing it exactly as they instruct. The example I'm following is here: https://www.npmjs.com/package/react-pdf

But the numPages state is a complete mystery to me. I'm setting it through the onDocumentLoadSuccess function on line 17, as in their Github docs example. But where it's supposed to be getting the { numPages } argument from, I have no idea. Because, as is, numPages remains undefined. And therefore, pageSelection (line 10) is never populated.

Maybe I'm missing something, but as far as I can tell, their documentation does not explain this: https://react-pdf.org/

Can someone help me out here?

import React, { useState } from 'react';
import { Document, Page, pdfjs } from 'react-pdf';

const PDFDisplay = (props) => {
    pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

    const [ numPages, setNumPages ] = useState(null);
    const [ pageNumber, setPageNumber ] = useState(1);

    let pageSelection;

    if (numPages) {
        pageSelection = Array(1 - numPages + 1).fill().map((_, idx) => 1 + idx);
        console.log(numPages.length);
    }
    
    const onDocumentLoadSuccess = ({ numPages }) => {
        setNumPages(numPages); 
    }

    const showPageSelection = () => {
        console.log(`numPages: ${numPages}`);
        return (
            <ul style={{ listStyle: 'none', display: 'inline-block' }}>
                { 
                    pageSelection.map(function(cur, idx) {
                        if (idx + 1 === pageNumber){
                            return <li><b>{idx + 1}</b></li>
                        } else {
                            return <li onClick={setPageNumber(idx)}>{idx + 1}</li>
                        }
                    })
                }
            </ul>
        );
    }

    return (
        <div>
            <Document
                file={props.file}
                onLoadSuccess={onDocumentLoadSuccess}
            >
                <Page pageNumber={pageNumber} />
            </Document>
            { numPages > 1 ? showPageSelection : null }
        </div>
    )
}

export default PDFDisplay;

2 Answers2

5

In onDocumentLoadSuccess(), you will get a complete object of document information; numPages is one of the property of this object.

So try accessing function like this, and see if you're getting all the PDF object, like below.

function onDocumentLoadSuccess(pdf)  {
    console.log('Document',pdf);
    setNumPages(pdf?.numPages);
}
Parag Raje
  • 53
  • 4
0

You should import Document in this manner import { Document } from 'react-pdf/dist/esm/entry.webpack' it should work, as it works for me. Here is OnLoad Function

const handlePDFLoadSuccess = ({ numPages }) => {
    setNumPages(numPages);
};

and here is how you should use Document component.

{selectedFile && <Document file={selectedFile} onLoadSuccess {handlePDFLoadSuccess}>
                    {numPages}
                 </Document>
 )}
Zahid Ali
  • 11
  • 2