React-pdf: Add onRenderSuccess to <Document> when <Page> elements finish rendering

Created on 6 May 2019  路  2Comments  路  Source: wojtekmaj/react-pdf

Before you start - checklist

  • [x] I understand that React-PDF does not aim to be a fully-fledged PDF viewer and is only a tool to make one
  • [x] I have checked if this feature request is not already reported

Is your feature request related to a problem? Please describe.

I'd like to have a central callback function on the <Document> element, that tells me that all <Page> elements have successfully rendered. Right now, I can only achieve this by implementing a callback on all <Page> elements using onRenderSuccess and accumulating all pages in a boolean array, to know when all pages are done rendering.

Describe the solution you'd like

Add a onRenderSuccess or onPageRenderSuccess attribute to the <Document> element, which is called when all pages have finished rendering.

Describe alternatives you've considered

Alternatively you can gather that information by creating a boolean array and gathering all the information by putting a onRenderSuccess callback on all your pages (through a loop or manually). This is pretty inconvenient, having to do this outside of the component, adding to the component state unnecessarily.

question

Most helpful comment

Just if somebody finds this, thanks @wojtekmaj, we pretty much went the way you did it. Just added a callback to the Page elements.

All 2 comments

Hmmm, this would be quite problemative with current architecture. Pages are rendered independently from Document, and Document doesn't really know about all Page instances that are inside. So we have no way of knowing how many pages are actually being rendered.

What component DO know what pages are being rendered? The one rendering it! So we can implement a function like this:

function makeOnAllPagesRenderedCallback(onAllPagesRendered) {
  const pages = [];

  function ref(pageComponent) {
    if (!pageComponent) {
      return;
    }

    // Register Page component at mount
    pages[pageComponent.pageIndex] = false;
  }

  function onRenderSuccess(page) {
    // Register page as rendered
    pages[page.pageIndex] = true;

    // If all pages registered are now rendered, call the callback
    if (pages.every(Boolean)) {
      onAllPagesRendered();
    }
  }

  return {
    ref,
    onRenderSuccess,
  };
}

// Usage: 

function onAllPagesRendered() {
  console.log('All pages rendered!');
}

const additionalProps = makeOnAllPagesRenderedCallback(onAllPagesRendered);

<Document>
  <Page pageNumber={1} {...additionalProps} />
  <Page pageNumber={3} {...additionalProps} />
</Document>

~Note: This solution requires a feature done in 14dcc676bf600c3e7fcbe1d37b8ebe1254126ede commit, so it requires the next release of react-pdf (react-pdf@>4.0.5), not out yet.~

Note: This solution requires [email protected] or later.

Just if somebody finds this, thanks @wojtekmaj, we pretty much went the way you did it. Just added a callback to the Page elements.

Was this page helpful?
0 / 5 - 0 ratings