Deutsch

Lernen Sie, wie Sie React Error Boundaries für eine elegante Fehlerbehandlung implementieren, um Anwendungsabstürze zu verhindern und die Benutzererfahrung zu verbessern.

React Error Boundaries: Ein umfassender Leitfaden für robuste Fehlerbehandlung

In der Welt der modernen Webentwicklung ist eine reibungslose und zuverlässige Benutzererfahrung von größter Bedeutung. Ein einziger unbehandelter Fehler kann eine gesamte React-Anwendung zum Absturz bringen, was Benutzer frustriert und potenziell zum Verlust wertvoller Daten führt. React Error Boundaries bieten einen leistungsstarken Mechanismus, um solche Fehler elegant zu behandeln, katastrophale Abstürze zu verhindern und eine widerstandsfähigere und benutzerfreundlichere Erfahrung zu bieten. Dieser Leitfaden bietet einen umfassenden Überblick über React Error Boundaries und behandelt deren Zweck, Implementierung, Best Practices und fortgeschrittene Techniken.

Was sind React Error Boundaries?

Error Boundaries sind React-Komponenten, die JavaScript-Fehler an jeder Stelle in ihrem untergeordneten Komponentenbaum abfangen, diese Fehler protokollieren und anstelle des abgestürzten Komponentenbaums eine Fallback-Benutzeroberfläche anzeigen. Sie fungieren als Sicherheitsnetz und verhindern, dass Fehler in einem Teil der Anwendung die gesamte Benutzeroberfläche lahmlegen. Eingeführt in React 16, ersetzten Error Boundaries die früheren, weniger robusten Fehlerbehandlungsmechanismen.

Stellen Sie sich Error Boundaries als `try...catch`-Blöcke für React-Komponenten vor. Im Gegensatz zu `try...catch` funktionieren sie jedoch für Komponenten und bieten eine deklarative und wiederverwendbare Möglichkeit, Fehler in Ihrer gesamten Anwendung zu behandeln.

Warum Error Boundaries verwenden?

Error Boundaries bieten mehrere entscheidende Vorteile:

Erstellen einer Error-Boundary-Komponente

Um eine Error-Boundary-Komponente zu erstellen, müssen Sie eine Klassenkomponente definieren, die eine oder beide der folgenden Lifecycle-Methoden implementiert:

Hier ist ein grundlegendes Beispiel für eine Error-Boundary-Komponente:


class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Zustand aktualisieren, damit beim nächsten Rendern die Fallback-UI angezeigt wird.
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    // Beispiel "componentStack":
    //   in ComponentThatThrows (created by App)
    //   in App
    console.error("Caught an error: ", error, info.componentStack);
    // Sie können den Fehler auch an einen Fehlerberichterstattungsdienst protokollieren
    // logErrorToMyService(error, info.componentStack);
  }

  render() {
    if (this.state.hasError) {
      // Sie können eine beliebige benutzerdefinierte Fallback-UI rendern
      return 

Etwas ist schiefgegangen.

; } return this.props.children; } }

Erklärung:

Verwendung von Error Boundaries

Um eine Error Boundary zu verwenden, umschließen Sie einfach die Komponente oder die Komponenten, die Sie schützen möchten, mit der ErrorBoundary-Komponente:



  


Wenn ComponentThatMightThrow einen Fehler auslöst, fängt die ErrorBoundary den Fehler ab, aktualisiert ihren Zustand und rendert ihre Fallback-UI. Der Rest der Anwendung funktioniert normal weiter.

Platzierung von Error Boundaries

Die Platzierung von Error Boundaries ist entscheidend für eine effektive Fehlerbehandlung. Berücksichtigen Sie diese Strategien:

Beispiel:


function App() {
  return (
    
); }

In diesem Beispiel ist jeder Hauptabschnitt der Anwendung (Header, Sidebar, ContentArea, Footer) mit einer Error Boundary umschlossen. Dies ermöglicht es jedem Abschnitt, Fehler unabhängig zu behandeln und verhindert, dass ein einzelner Fehler die gesamte Anwendung beeinträchtigt.

Anpassen der Fallback-UI

Die von einer Error Boundary angezeigte Fallback-UI sollte informativ und benutzerfreundlich sein. Beachten Sie diese Richtlinien:

Beispiel:


class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Zustand aktualisieren, damit beim nächsten Rendern die Fallback-UI angezeigt wird.
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    // Sie können den Fehler auch an einen Fehlerberichterstattungsdienst protokollieren
    console.error("Caught an error: ", error, info.componentStack);
  }

  render() {
    if (this.state.hasError) {
      // Sie können eine beliebige benutzerdefinierte Fallback-UI rendern
      return (
        

Hoppla! Etwas ist schiefgegangen.

Es tut uns leid, aber beim Versuch, diesen Inhalt anzuzeigen, ist ein Fehler aufgetreten.

Bitte versuchen Sie, die Seite zu aktualisieren, oder kontaktieren Sie den Support, falls das Problem weiterhin besteht.

Support kontaktieren
); } return this.props.children; } }

Dieses Beispiel zeigt eine informativere Fallback-UI, die eine klare Fehlermeldung, Lösungsvorschläge und Links zum Aktualisieren der Seite und zur Kontaktaufnahme mit dem Support enthält.

Umgang mit verschiedenen Fehlertypen

Error Boundaries fangen Fehler ab, die während des Renderns, in Lifecycle-Methoden und in Konstruktoren des gesamten Baumes unter ihnen auftreten. Sie fangen Fehler *nicht* ab für:

Um diese Arten von Fehlern zu behandeln, müssen Sie andere Techniken anwenden.

Event-Handler

Für Fehler, die in Event-Handlern auftreten, verwenden Sie einen standardmäßigen try...catch-Block:


function MyComponent() {
  const handleClick = () => {
    try {
      // Code, der einen Fehler auslösen könnte
      throw new Error("Im Event-Handler ist etwas schiefgegangen");
    } catch (error) {
      console.error("Fehler im Event-Handler: ", error);
      // Den Fehler behandeln (z.B. eine Fehlermeldung anzeigen)
      alert("Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.");
    }
  };

  return ;
}

Asynchroner Code

Für Fehler, die in asynchronem Code auftreten, verwenden Sie try...catch-Blöcke innerhalb der asynchronen Funktion:


function MyComponent() {
  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch("https://api.example.com/data");
        const data = await response.json();
        // Die Daten verarbeiten
        console.log(data);
      } catch (error) {
        console.error("Fehler beim Abrufen der Daten: ", error);
        // Den Fehler behandeln (z.B. eine Fehlermeldung anzeigen)
        alert("Daten konnten nicht abgerufen werden. Bitte versuchen Sie es später erneut.");
      }
    }

    fetchData();
  }, []);

  return 
Daten werden geladen...
; }

Alternativ können Sie einen globalen Fehlerbehandlungsmechanismus für nicht behandelte Promise-Rejections verwenden:


window.addEventListener('unhandledrejection', function(event) {
  console.error('Unbehandelte Ablehnung (Promise: ', event.promise, ', Grund: ', event.reason, ');');
  // Optional eine globale Fehlermeldung anzeigen oder den Fehler an einen Dienst protokollieren
  alert("Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.");
});

Fortgeschrittene Error-Boundary-Techniken

Zurücksetzen der Error Boundary

In einigen Fällen möchten Sie den Benutzern möglicherweise eine Möglichkeit bieten, die Error Boundary zurückzusetzen und den Vorgang, der den Fehler verursacht hat, erneut zu versuchen. Dies kann nützlich sein, wenn der Fehler durch ein temporäres Problem, wie z.B. ein Netzwerkproblem, verursacht wurde.

Um eine Error Boundary zurückzusetzen, können Sie eine Zustandsverwaltungsbibliothek wie Redux oder Context verwenden, um den Fehlerzustand zu verwalten und eine Reset-Funktion bereitzustellen. Alternativ können Sie einen einfacheren Ansatz verwenden, indem Sie das Remounting der Error Boundary erzwingen.

Beispiel (Erzwingen des Remountings):


class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, errorCount: 0, key: 0 };
  }

  static getDerivedStateFromError(error) {
    // Zustand aktualisieren, damit beim nächsten Rendern die Fallback-UI angezeigt wird.
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    // Sie können den Fehler auch an einen Fehlerberichterstattungsdienst protokollieren
    console.error("Caught an error: ", error, info.componentStack);
    this.setState(prevState => ({ errorCount: prevState.errorCount + 1 }));
  }

  resetError = () => {
      this.setState({hasError: false, key: this.state.key + 1})
  }

  render() {
    if (this.state.hasError) {
      // Sie können eine beliebige benutzerdefinierte Fallback-UI rendern
      return (
        

Hoppla! Etwas ist schiefgegangen.

Es tut uns leid, aber beim Versuch, diesen Inhalt anzuzeigen, ist ein Fehler aufgetreten.

); } return
{this.props.children}
; } }

In diesem Beispiel wird dem umschließenden Div ein 'key' hinzugefügt. Das Ändern des Keys erzwingt das Remounting der Komponente, wodurch der Fehlerzustand effektiv gelöscht wird. Die `resetError`-Methode aktualisiert den `key`-Zustand der Komponente, was dazu führt, dass die Komponente neu gemountet wird und ihre Kinder neu rendert.

Verwendung von Error Boundaries mit Suspense

React Suspense ermöglicht es Ihnen, das Rendern einer Komponente zu "unterbrechen", bis eine bestimmte Bedingung erfüllt ist (z.B. Daten werden abgerufen). Sie können Error Boundaries mit Suspense kombinieren, um eine robustere Fehlerbehandlung für asynchrone Operationen zu gewährleisten.


import React, { Suspense } from 'react';

function MyComponent() {
  return (
    
      Wird geladen...
}> ); } function DataFetchingComponent() { const data = useData(); // Benutzerdefinierter Hook, der Daten asynchron abruft return
{data.value}
; }

In diesem Beispiel ruft die DataFetchingComponent Daten asynchron mit einem benutzerdefinierten Hook ab. Die Suspense-Komponente zeigt einen Ladeindikator an, während die Daten abgerufen werden. Wenn während des Datenabrufs ein Fehler auftritt, fängt die ErrorBoundary den Fehler ab und zeigt eine Fallback-UI an.

Best Practices für React Error Boundaries

Praxisbeispiele

Hier sind einige Praxisbeispiele, wie Error Boundaries verwendet werden können:

Alternativen zu Error Boundaries

Obwohl Error Boundaries die empfohlene Methode zur Fehlerbehandlung in React sind, gibt es einige alternative Ansätze, die Sie in Betracht ziehen können. Bedenken Sie jedoch, dass diese Alternativen möglicherweise nicht so effektiv sind wie Error Boundaries, um Anwendungsabstürze zu verhindern und eine nahtlose Benutzererfahrung zu bieten.

Letztendlich bieten Error Boundaries einen robusten und standardisierten Ansatz zur Fehlerbehandlung in React und sind daher für die meisten Anwendungsfälle die bevorzugte Wahl.

Fazit

React Error Boundaries sind ein wesentliches Werkzeug für die Erstellung robuster und benutzerfreundlicher React-Anwendungen. Indem sie Fehler abfangen und Fallback-UIs anzeigen, verhindern sie Anwendungsabstürze, verbessern die Benutzererfahrung und vereinfachen das Debugging von Fehlern. Wenn Sie die in diesem Leitfaden beschriebenen Best Practices befolgen, können Sie Error Boundaries effektiv in Ihren Anwendungen implementieren und eine widerstandsfähigere und zuverlässigere Benutzererfahrung für Benutzer auf der ganzen Welt schaffen.