react-pdf: Can't perform a React state update on an unmounted component

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

Description

With the following component, I have this warning:

Warning: Can’t perform a React state update on an unmounted component.

screenshot 2019-02-13 at 18 59 36

Steps to reproduce

This is the problematic component:

class Pdf extends Component {
  state = { numPages: 0 }

  onDocumentLoad = ({ numPages }) => this.setState({ numPages })

  render() {
    const { numPages } = this.state
    const { url } = this.props

    const headers = { withCredentials: true }

    return (
      <Document file={{ headers, url }} onLoadSuccess={this.onDocumentLoad}>
        {range(0, numPages).map(index => (
          <Page key={index} pageIndex={index} />
        ))}
      </Document>
    )
  }
}

Expected behavior

If I remove the setState, the PDF renders properly but I lose the information about the number of pages.

Additional information

This is the example from the README and this was perfectly working before I upgraded to v4.

Environment

  • React-PDF version: 4.0.2
  • React version: 16.8.1
  • Webpack version (if applicable): 4.29.3

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 21 (7 by maintainers)

Commits related to this issue

Most upvoted comments

I ran into this issue while using this library in a next.js project.

My understanding is that the error happens during rerenders - in my case, when onLoadSuccess is called to update numberOfPages.

My current solution is to use useMemo to memoize the file object. The error disappears completely if I do this.

function PreviewPDF(props) {
  const [numberOfPages, setNumberOfPages] = useState(null);
  const [pageNumber, setPageNum] = useState(1);
  const file = useMemo(
    () => ({ url: props.fileSrc, withCredentials: true }),
    []
  );

  return (
    <Portal>
      <Document
          file={file}
          onLoadSuccess={({ numPages }) => setNumberOfPages(numPages)}
          options={{ cMapUrl: '/_next/cmaps/', cMapPacked: true }}
        >
          <Page pageNumber={pageNumber} />
      </Document>
    </Portal>
  );
}

Where props.fileSrc is required.

Hope this helps.

Would also be interested in hearing the solution to this. Error is appearing in a component using React Hooks, so I’m not sure how that plays into the mix.

@wojtekmaj I am able to get it work by doing like this : screen shot 2019-02-18 at 5 20 07 pm

Hello @Kerumen ,

try this:

onDocumentLoad = (document) => {
  const { numPages } = document;
  this.setState({
    numPages,
  });
};

see the example here

@msgfxeg Don’t think that’s the case (this repo is not affected), but using file object without memoizing sure can cause the issue desribed.