Bevor Sie beginnen - Checkliste
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.
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
4.0.2
16.8.1
4.29.3
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,
"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:
@wojtekmaj Ich kann es so machen:
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?
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?
@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.
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, umnumberOfPages
zu aktualisieren.Meine aktuelle Lösung besteht darin,
useMemo
zum Speichern des Dateiobjekts zu verwenden. Der Fehler verschwindet vollständig, wenn ich dies tue.Wo
props.fileSrc
erforderlich ist.Hoffe das hilft.