React-pdf: Es kann keine Aktualisierung des Reaktionsstatus für eine nicht gemountete Komponente durchgeführt werden

Erstellt am 13. Feb. 2019  ·  19Kommentare  ·  Quelle: wojtekmaj/react-pdf

Bevor Sie beginnen - Checkliste

  • [x] Ich habe die Anweisungen in der Dokumentation für meine React-PDF-Version befolgt
  • [x] Ich habe überprüft, ob dieser Fehler noch nicht gemeldet wurde
  • [x] Ich habe überprüft, ob ein Problem nicht unter Bekannte Probleme aufgeführt ist

Beschreibung

Mit der folgenden Komponente habe ich diese Warnung:

Warnung: Es kann keine Aktualisierung des Reaktionsstatus für eine nicht gemountete Komponente durchgeführt werden.

screenshot 2019-02-13 at 18 59 36

Schritte zum Reproduzieren

Dies ist die problematische Komponente:

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>
    )
  }
}

Erwartetes Verhalten

Wenn ich setState entferne, wird das PDF ordnungsgemäß gerendert, aber ich verliere die Informationen über die Anzahl der Seiten.

Zusätzliche Information

Dies ist das Beispiel aus der README-Datei, das vor dem Upgrade auf Version 4 einwandfrei funktioniert hat.

Umgebung

  • React-PDF-Version: 4.0.2
  • Reaktionsversion: 16.8.1
  • Webpack-Version (falls zutreffend): 4.29.3
bug

Hilfreichster Kommentar

Ich bin auf dieses Problem gestoßen, als ich diese Bibliothek in einem next.js-Projekt verwendet habe.

Ich verstehe, dass der Fehler beim erneuten Rendern auftritt - in meinem Fall, wenn onLoadSuccess aufgerufen wird, um numberOfPages zu aktualisieren.

Meine aktuelle Lösung besteht darin, useMemo zum Speichern des Dateiobjekts zu verwenden. Der Fehler verschwindet vollständig, wenn ich dies tue.

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>
  );
}

Wo props.fileSrc erforderlich ist.

Hoffe das hilft.

Alle 19 Kommentare

Hallo @Kerumen ,

Versuche dies:

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

siehe das Beispiel hier

@ Kerumen hast du es zum

@ Maxhou00
Es funktioniert gut, wenn wir Dateien direkt aus dem Bundle laden. Aber wenn wir PDF von einer URL laden, ist das gleiche Problem.

Ich habe den hier erwähnten Ansatz ausprobiert,
screen shot 2019-02-18 at 1 35 51 pm

"Warnung: Es kann keine Aktualisierung des Reaktionsstatus für eine nicht gemountete Komponente durchgeführt werden. Dies ist ein No-Op, zeigt jedoch einen Speicherverlust in Ihrer Anwendung an. Um dies zu beheben, kündigen Sie alle Abonnements und asynchronen Aufgaben in der componentWillUnmount-Methode.
in PageInternal (erstellt von Context.Consumer)
in Seite (bei Test.js: 30) "

@qaisershehzad Vielleicht definieren Sie mit jedem Rendering ein neues file Objekt? Siehe # 308

@wojtekmaj Ich mache das:
screen shot 2019-02-18 at 4 55 52 pm

@wojtekmaj Ich kann es so machen:
screen shot 2019-02-18 at 5 20 07 pm

Ich hatte auch die gleiche Meldung "Statusaktualisierung auf eine nicht gemountete Komponente reagieren". Dies schien jedoch zu passieren, als ich ein mehrseitiges PDF im React-PDF geöffnet hatte und vor dem Laden der ersten Seite von einer Seite zur anderen wechselte.

Mein "Fix" bestand darin, alle Steuerelemente zu deaktivieren, bis das Ereignis "onRenderSuccess" beim Laden einer Seite ausgelöst wurde. Versuchen Sie, eine neue Seite zu laden: Deaktivieren Sie alle Steuerelemente und warten Sie auf "onRenderSuccess". Ich weiß jedoch nicht, ob dies übertrieben ist. @wojtekmaj :

Wir sollten in der Lage sein, den Einstellungsstatus beim Aufheben der Bereitstellung von PageInternal abzubrechen. Dies klingt also nach einem Fehler, der relativ einfach zu beheben wäre. Ich denke nicht, dass es sich lohnt, alle Steuerelemente zu deaktivieren - der Fehler selbst führt nicht zum Absturz -, aber es ist eine Problemumgehung, die dies tun sollte, wenn Sie diese Nachricht vorerst wirklich nicht sehen möchten :)

Danke für deinen Kommentar. Ich würde mich darauf freuen, dass dieser Fehler behoben wird.

Hallo @peterkmurphy , ich habe das gleiche Problem, bin mir aber nicht sicher, was Sie unter Deaktivieren von Steuerelementen verstehen, bis onRenderSuccess aufgerufen wird. Ich mache das:

onRenderSuccess = () => {
  this.setState({
    renderSuccess: true
  });
};

...

{renderSuccess && numPages && numPages.lengh > 1 && (
  <>
    <p>
      Page {pageNumber || (numPages ? 1 : '--')} of{' '}
      {numPages || '--'}
    </p>
    <button
      type="button"
      disabled={pageNumber <= 1}
      onClick={this.previousPage}
    >
      Previous
    </button>
    <button
      type="button"
      disabled={pageNumber >= numPages}
      onClick={this.nextPage}
    >
      Next
    </button>
  </>
)}

Können Sie bitte Ihre Lösung näher erläutern? Vielen Dank :)

Wäre auch daran interessiert, die Lösung dafür zu hören. In einer Komponente mit React Hooks tritt ein Fehler auf, daher bin ich mir nicht sicher, wie sich das auf die Mischung auswirkt.

Ich bin auf dieses Problem gestoßen, als ich diese Bibliothek in einem next.js-Projekt verwendet habe.

Ich verstehe, dass der Fehler beim erneuten Rendern auftritt - in meinem Fall, wenn onLoadSuccess aufgerufen wird, um numberOfPages zu aktualisieren.

Meine aktuelle Lösung besteht darin, useMemo zum Speichern des Dateiobjekts zu verwenden. Der Fehler verschwindet vollständig, wenn ich dies tue.

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>
  );
}

Wo props.fileSrc erforderlich ist.

Hoffe das hilft.

@qaisershehzad Ich habe mich fast 2 Tage lang durchgeschlagen. Ihr Ansatz, das gesamte Dateiobjekt in den Status zu versetzen, hat mir schließlich geholfen. Vielen Dank

Das Auswendiglernen / Aufrechterhalten von Objekten ist die richtige, empfohlene Lösung. Ich werde sicherstellen, dass diese Angelegenheit besser dokumentiert wird, bis wir eine bessere Lösung gefunden haben (wie das Commit, auf das ich gerade verwiesen habe - in Arbeit, aber "scheint gut zu funktionieren").

Die Anforderung wird abgebrochen, wenn die Komponente ausgehängt wird. Das Versprechen lehnen Sie dann ab.
https://github.com/wojtekmaj/react-pdf/blob/590077862132d86da44ac0dc59fc99aaf1e99224/src/Page.jsx#L77

  componentWillUnmount() {
    const { unregisterPage } = this.props;

    callIfDefined(
      unregisterPage,
      this.pageIndex,
    );

    cancelRunningTask(this.runningTask);
  }

In loadPage :
https://github.com/wojtekmaj/react-pdf/blob/590077862132d86da44ac0dc59fc99aaf1e99224/src/Page.jsx#L264

    try {
      const cancellable = makeCancellable(pdf.getPage(pageNumber));
      this.runningTask = cancellable;
      const page = await cancellable.promise;
      this.setState({ page }, this.onLoadSuccess);
    } catch (error) {
      this.setState({ page: false });
      this.onLoadError(error);
    }

Ich denke jedoch, dass der Fehler klassifiziert werden sollte, um festzustellen, ob es sich um einen Netzwerkfehler oder um abgebrochene Aufgaben handelt. Wenn es durch Aufheben der Bereitstellung der Lebenszyklusmethode abgebrochen wird, sollte es nicht setState setzen oder etwas anderes tun.
Wie der Code unten:

    try {
      const cancellable = makeCancellable(pdf.getPage(pageNumber));
      this.runningTask = cancellable;
      const page = await cancellable.promise;
      this.setState({ page }, this.onLoadSuccess);
    } catch (error) {
        if (error.msg && error.msg === 'cancelled') {
            return;
        }

      this.setState({ page: false });
      this.onLoadError(error);
    }

@wojtekmaj

Der gleiche Fehler tritt auch auf, wenn versucht wird, numPages auf einer bereitgestellten Komponente zu aktualisieren.
"Warnung: Es kann keine Aktualisierung des Reaktionsstatus für eine nicht gemountete Komponente durchgeführt werden."

Datei wird bereits im Status verwendet - das Problem tritt nur bei Verwendung von onDocumentLoadSuccess auf:
onDocumentLoadSuccess = (document) => { console.log('doc loaded!') if(this.state.numPages == null) { this.setState({ numPages: document.numPages }) } }

Hmm, habe deinen onDocumentLoadSuccess reproduziert und ich kann den Fehler @ scottie-schneider nicht sehen :( Willst du einen Blick darauf werfen?

https://codesandbox.io/s/little-hooks-bbgek

Hallo,
Ich habe das gleiche Problem, aber mit einem Puffer, den ich von Redux lade, gerät er in eine Schleife. Dies geschieht nur, wenn ich den Status beim erfolgreichen Laden von Dokumenten aktualisiere.

Hmm, habe deinen onDocumentLoadSuccess reproduziert und ich kann den Fehler @ scottie-schneider nicht sehen :( Willst du einen Blick darauf werfen?

https://codesandbox.io/s/little-hooks-bbgek

@wojtekmaj
Es funktioniert mit Ihnen, da Ihr PDF nur eine Seite enthält. Der Fehler / die Warnung besteht immer noch auf mehrseitigen PDFs!

@msgfxeg Ich glaube nicht, dass dies der Fall ist ( dieses Repo ist nicht betroffen), aber die Verwendung eines Dateiobjekts ohne Auswendiglernen kann das beschriebene Problem verursachen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen