Was ich verstanden habe hier:
componentDidCatch
:
- wird immer im Browser aufgerufen
- wird während der “Commit-Phase” aufgerufen, wenn das DOM bereits aktualisiert wurde
- sollte für so etwas wie das Melden von Fehlern verwendet werden
getDerivedStateFromError
:
- wird auch beim serverseitigen Rendern aufgerufen
- wird in der “Renderphase” aufgerufen, wenn das DOM noch nicht aktualisiert wurde
- sollte zum Rendern einer Fallback-Benutzeroberfläche verwendet werden
Trotzdem bin ich etwas verwirrt über einige Dinge:
- Fangen sie beide die gleiche Art von Fehlern? oder wird jeder Lebenszyklus den anderen Fehler abfangen?
- sollte ich immer beide verwenden (möglicherweise in derselben “fehlerfangenden” Komponente)?
- „Die Verwendung von „componentDidCatch“ zur Fehlerbehebung ist nicht optimal, da es die Fallback-Benutzeroberfläche dazu zwingt, immer synchron zu rendern.“ was stimmt damit nicht?
Die Aussagen in der Frage sind größtenteils richtig. Derzeit werden Fehlergrenzen in SSR nicht unterstützt, getDerivedStateFromError
und componentDidCatch
wirken sich nicht auf die Serverseite aus.
Fangen sie beide die gleiche Art von Fehlern? oder wird jeder Lebenszyklus den anderen Fehler abfangen?
Sie fangen dieselben Fehler ab, aber in unterschiedlichen Phasen. Dies war bisher mit möglich componentDidCatch
allein:
static getDerivedStateFromError() {
return { hasError: true };
}
und
componentDidCatch() {
this.setState({ hasError: true });
}
mach das selbe, componentDidCatch
hat keine Chance, serverseitig unterstützt zu werden, bis die Unterstützung für asynchrones Rendering hinzugefügt wird ReactDOMServer
.
sollte ich immer beide verwenden (möglicherweise in derselben “fehlerfangenden” Komponente)?
Du kann verwende beide. Ein Beispiel aus die Dokumentation zeigt, dass:
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, info) {
logComponentStackToMyService(info.componentStack);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
In diesem Fall werden die Verantwortlichkeiten zwischen ihnen aufgeteilt. getDerivedStateFromError
tut das einzige, wofür es gut ist, dh aktualisiert den Zustand, wenn ein Fehler auftritt, während componentDidCatch
bietet Nebenwirkungen und kann zugreifen this
Komponenteninstanz, falls erforderlich.
“Die Verwendung von componentDidCatch zur Fehlerbehebung ist nicht optimal, da die Fallback-Benutzeroberfläche gezwungen wird, immer synchron zu rendern.” Was ist daran falsch?
Neue React-Releases zielen auf asynchrones Rendering ab, das effizienter ist. Wie auch schon erwähnt in der Kommentarist das synchrone Rendering kein großes Problem für die Fallback-Benutzeroberfläche, da dies als Randfall betrachtet werden kann.
Diese beiden Methoden werden aufgerufen, wenn während des Renderns, in einer Lebenszyklusmethode oder im Konstruktor einer untergeordneten Komponente ein Fehler auftritt. Sie können beim Implementieren von Fehlergrenzen verwendet werden
Laut dem Reagieren Sie auf Dokumente
getDerivedStateFromError
lifecycle wird aufgerufen, nachdem eine untergeordnete Komponente einen Fehler ausgegeben hat. Es empfängt den Fehler, der als Parameter ausgelöst wurde, und sollte einen Wert für den Aktualisierungsstatus zurückgeben.
Fangen sie beide die gleiche Art von Fehlern? oder wird jeder Lebenszyklus den anderen Fehler abfangen?
Beide Lebenszyklusmethoden fangen die gleichen Fehler ab, aber die Argumente für diese beiden Komponenten sind unterschiedlich.
Während getDerivedStateFromError
erhält nur den Fehler als Argumente, componentDidCatch erhält auch den zweiten Parameter, nämlich info, i.e An object with a componentStack key containing information about which component threw the error.
getDerivedStateFromError()
wird während der „Render“-Phase aufgerufen, daher sind keine Nebeneffekte zulässig. Verwenden Sie für diese Anwendungsfälle componentDidCatch()
stattdessen. Während componentDidCatch
kann auch für setState verwendet werden, aber dies wird in zukünftigen Versionen veraltet sein
componentDidCatch
sollte für Nebeneffekte wie Protokollierungsfehler verwendet werden
Ebenfalls @Brian Vaughn
hat mehr über ihre Verwendung unter dem von Ihnen bereitgestellten Link erläutert
getDerivedStateFromError
arbeitet mit serverseitigem Rendering.
componentDidCatch ist ein Commit-Phasen-Lebenszyklus, aber es gibt keine Commit-Phase auf dem Server. getDerivedStateFromError ist ein Renderphasen-Lebenszyklus und kann daher verwendet werden, um die Fehlerbehandlung auf dem Server zu aktivieren.
Die Wiederherstellung der Renderphase ist sicherer. Die Geschichte zur Fehlerbehebung über
componentDidCatch
ist ein wenig ruckelig, da es für alles unterhalb der fehlerhaften Komponente auf einen Zwischencommit von “null” angewiesen ist. Dies kann zu nachfolgenden Fehlern innerhalb von Komponenten weiter oben im Baum führen, die „componentDidMount“ oder „componentDidUpdate“ implementieren und einfach davon ausgehen, dass ihre Refs nicht null sind (weil sie sich immer im Nicht-Fehlerfall befinden).
getDerivedStateFromError
erzwingt kein synchrones Rendern. Da Zustandsaktualisierungen aus Commit-Phasen-Lebenszyklen immer synchron sind und weil „componentDidCatch“ während der Commit-Phase aufgerufen wird, ist die Verwendung von „componentDidCatch“ für die Fehlerbehebung nicht optimal, da sie die Fallback-Benutzeroberfläche dazu zwingt, immer synchron zu rendern. (Dies ist zugegebenermaßen kein großes Problem, da die Fehlerbehebung ein Randfall sein sollte.)
Im Fehlerfall gilt Ihre Fehlergrenze
getDerivedStateFromError()
-Methode wird zuerst aufgerufen (um den Status zu aktualisieren), dann die render() -Methode (um die Fallback-Benutzeroberfläche tatsächlich zu rendern) und dann componentDidCatch
(sobald die Fallback-Benutzeroberfläche an das DOM übergeben wurde).
Wenn Ihre Fehlergrenze andere Lebenszyklusmethoden definiert (z. B. „componentWillUpdate“, „componentDidUpdate“), werden sie ebenfalls aufgerufen, genau wie bei jedem anderen Rendering.
“Die Verwendung von componentDidCatch zur Fehlerbehebung ist nicht optimal, da die Fallback-Benutzeroberfläche gezwungen wird, immer synchron zu rendern.” Was ist daran falsch?
Das bedeutet, dass „componentDidCatch“ nach der „render“-Methode aufgerufen wird, die die Fallback-UI rendert, was zu weiteren Problemen führen kann getDerivedStateFromError
aktualisiert den Status vor der Renderphase, sodass die richtige Fallback-Benutzeroberfläche gerendert wird und keine weiteren Fehler in den gerenderten Komponenten verursacht werden. Außerdem zielen die neuen Versionen auf asynchrones Rendern ab, was mit dem aktuellen Ansatz Probleme haben könnte
Eigentlich haben beide das gleiche Ziel, aber in einer anderen Phase, definitiv, zum Schreiben ErrorBoundary
Komponente, die ich verwende getDerivedStateFromError
Methode, weil ich der gehorche ReactJs-Dokumentation. Das Dokument hat diesen Satz:
Statik verwenden getDerivedStateFromError()
um eine Fallback-Benutzeroberfläche zu rendern, nachdem ein Fehler ausgelöst wurde. Verwenden componentDidCatch()
um Fehlerinformationen zu protokollieren.
Sicherlich hat es einige Gründe, die ich immer zum Rendern der Fallback-Benutzeroberfläche verwende getDerivedStateFromError
und um Informationen zu sammeln und etwas zu tun, das ich benutze componentDidCatch
.