Error Boundary — co to jest, komponent React Native i obsługa błędów

Autor: IT Sectr Opublikowano: 2026-05-27 Czas czytania: 8 min

Error Boundary — to komponent React, który przechwytuje błędy JavaScript w swoim drzewie komponentów potomnych i wyświetla interfejs zastępczy zamiast strony crasha. W kontekście React Native zapobiega całkowitemu zawieszeniu aplikacji przy niekrytycznych błędach renderowania. Według React Documentation, 2024, error boundary przechwytuje błędy w metodach render, lifecycle-hookach i konstruktorach komponentów potomnych, umożliwiając kontynuację działania aplikacji. W React Native jest to szczególnie krytyczne, ponieważ aplikacja mobilna nie przeładowuje się przez F5 — użytkownik traci całą sesję.

Najważniejsze

  • Error Boundary — komponent React do przechwytywania błędów renderowania w drzewie potomnym
  • ComponentDidCatch — metoda cyklu życia, otrzymująca błąd i informację o stosie
  • Fallback UI — interfejs zastępczy wyświetlany zamiast uszkodzonego komponentu
  • React Native używa Error Boundary do zapobiegania całkowitemu crashowi aplikacji
  • Ograniczenie — Error Boundary nie przechwytuje błędów w kodzie asynchronicznym i event-handlerach

Co to jest Error Boundary

Error Boundary — to mechanizm React do graceful degradation przy błędach renderowania. Wprowadzony w React 16 (2017) jako komponent-opakowujący, implementujący jedną z dwóch metod cyklu życia: static getDerivedStateFromError lub componentDidCatch. Error Boundary pozwala wyświetlić użytkownikowi zrozumiały komunikat zamiast pustego białego ekranu lub całkowitego crasha aplikacji.

Jak powstał Error Boundary

Przed React 16 każdy nieobsłużony błąd w render prowadził do crasha całej aplikacji z odmontowaniem całego drzewa DOM. W aplikacjach web oznaczało to pusty biały ekran, w React Native — całkowity crash aplikacji z powrotem do Home Screen. Zespół React wprowadził Error Boundary jako odpowiednik catch-bloku dla deklaratywnego UI, zapożyczając koncepcję z podejścia „let it crash” w języku Erlang.

Znaczenie dla React Native

W React Native brak Error Boundary oznacza całkowity crash aplikacji przy każdym błędzie renderowania. Użytkownik traci całą bieżącą sesję bez możliwości odzyskania. Error Boundary w React Native jest krytycznie ważny, ponieważ aplikacje mobilne nie przeładowują się jak strony internetowe — sesja użytkownika jest bezpowrotnie tracona i użytkownik musi zaczynać wszystko od nowa.

Jak działa Error Boundary w React Native

Error Boundary działa na poziomie drzewa React. Gdy komponent potomny wyrzuca błąd w render lub lifecycle, React nie odmontowuje całego drzewa, lecz przekazuje sterowanie do najbliższego Error Boundary wyżej w hierarchii. Boundary wywołuje getDerivedStateFromError, ustawia state.hasError = true i renderuje fallback UI zamiast uszkodzonej gałęzi komponentów.

typescript
import React, { Component, ErrorInfo, ReactNode } from "react"

interface Props {
    children: ReactNode
    fallback?: ReactNode
}

interface State {
    hasError: boolean
    error?: Error
}

class ErrorBoundary extends Component<Props, State> {
    constructor(props: Props) {
        super(props)
        this.state = { hasError: false }
    }

    static getDerivedStateFromError(error: Error): State {
        return { hasError: true, error }
    }

    componentDidCatch(error: Error, info: ErrorInfo) {
        console.error("Przechwycone przez boundary:", error)
        Crashlytics.recordException(error)
    }

    render() {
        if (this.state.hasError) {
            return this.props.fallback || <FallbackUI />
        }
        return this.props.children
    }
}

getDerivedStateFromError ustawia stan do renderowania fallback UI — to metoda statyczna wywoływana na etapie renderowania przed zatwierdzeniem zmian. componentDidCatch wykonuje się na etapie zatwierdzania i jest przeznaczony do efektów ubocznych: logowania, wysyłania crash-reportów do Crashlytics, analityki. Dwie metody dzielą odpowiedzialność między zarządzaniem stanem UI a działaniami ubocznymi.

Tworzenie komponentu Error Boundary

Aby utworzyć Error Boundary, należy zaimplementować komponent klasowy z metodami getDerivedStateFromError i/lub componentDidCatch. Komponenty funkcyjne nie mogą być Error Boundary — React wspiera tę funkcjonalność tylko dla komponentów klasowych, ponieważ wymagany jest dostęp do metod cyklu życia. W bibliotece react-error-boundary dostępna jest gotowa implementacja z API hooków dla wygody.

typescript
// Przykład użycia Error Boundary w React Native
import { ErrorBoundary } from "react-error-boundary"

const FallbackComponent = ({ error, resetError }: FallbackProps) => (
    <View style={styles.container}>
        <Text>Coś poszło nie tak</Text>
        <Text>{error.message}</Text>
        <Button title="Ponów" onPress={resetError} />
    </View>
)

const App = () => (
    <SafeAreaView>
        <ErrorBoundary FallbackComponent={<FallbackComponent />}>
            <UserProfile userId={"123"} />
        </ErrorBoundary>
        <BottomNavigation />
    </SafeAreaView>
)

Poziomy opakowania — Error Boundary można umieszczać na różnych poziomach hierarchii. Jeden globalny Boundary na korzeniu aplikacji pokaże fallback UI przy każdym błędzie, ale nawigacja nadal będzie działać. Kilka Boundary na poziomie ekranów pozwala izolować błędy: jeśli jeden ekran się zepsuł, pozostałe działają niezależnie. react-error-boundary upraszcza mechanizm Reset przez hook useErrorBoundary, umożliwiając zresetowanie stanu bez przeładowania. Dla typowych projektów schemat z trzema poziomami Boundary jest uważany za optymalny dla aplikacji React Native.

Resetowanie stanu Error Boundary

Po wystąpieniu błędu użytkownik może nacisnąć przycisk „Ponów”, który resetuje hasError na false i ponownie renderuje drzewo potomne. Mechanizm Reset jest ważny dla przywrócenia działania aplikacji bez przeładowania. W react-error-boundary używany jest callback onReset, który może czyścić cache, ponownie pobierać dane lub aktualizować stan wyżej w drzewie.

Ograniczenia Error Boundary

Error Boundary nie przechwytuje błędów asynchronicznych — błędów w setTimeout, setInterval, Promise, async/await. React nie może przechwycić błędów poza cyklem render i lifecycle-hookami, ponieważ są one wykonywane w innych kontekstach wykonania. Dla błędów asynchronicznych wymagany jest osobny try-catch w handlerach lub globalny handler zdarzenia unhandledrejection.

Event-handlery

Błędy w onClick, onChange i innych event-handlerach nie są przechwytywane przez Error Boundary, ponieważ są wykonywane poza renderowaniem React. Obsługa błędów dla event-handlerów powinna być wewnątrz samego handlera przez try-catch. Biblioteka react-error-boundary udostępnia hook useErrorHandler do przekazywania błędów z event-handlerów do najbliższego Boundary.

Server-side rendering i Next.js

Error Boundary nie działa po stronie serwera w Next.js lub Gatsby. Metody getDerivedStateFromError i componentDidCatch nie są wywoływane przy SSR, ponieważ metody cyklu życia są dostępne tylko w przeglądarce. Dla błędów serwerowych wymagana jest osobna strategia: try-catch w getServerSideProps, strony fallbackowe error.js (Next.js 13+) lub globalny middleware.

Warstwa natywna React Native

W React Native Error Boundary nie zapobiega crashom na poziomie modułów natywnych. Crash natywny (segfault, out-of-memory, wyjątek natywny) występuje na poziomie Objective-C lub Java i nie dociera do warstwy JavaScript. Dla crashy natywnych wymagany jest Crashlytics NDK (Android) lub KSCrash (iOS). Error Boundary chroni tylko warstwę JavaScript aplikacji React Native.

Najlepsze praktyki Error Boundary

Umieszczaj Error Boundary na granicach modułów znaczeniowych: jeden Boundary na ekran, jeden na widget zewnętrznego developera, jeden na złożony formularz. To izoluje błędy i pozwala użytkownikowi kontynuować pracę w pozostałych częściach aplikacji. Korzeniowy Boundary powinien być zawsze — na wypadek krytycznych błędów w wspólnych komponentach nawigacji lub providerach. Każdy Boundary odpowiada za swój fragment interfejsu i nie wpływa na sąsiednie komponenty przy wystąpieniu błędu.

Logowanie i monitorowanie

Zawsze przekazuj błąd do Crashlytics lub Sentry przez componentDidCatch. Dodawaj kontekst: nazwę ekranu, userId, wersję aplikacji, parametry nawigacji. W Sentry dostępne są breadcrumbs — sekwencja działań użytkownika przed błędem. Do analizy częstotliwości błędów non-fatal używaj dashboardów Crashlytics z grupowaniem według issue.

Fallback UI

Nie używaj „gołego” fallbacka — twórz znaczący interfejs. Zalecany zestaw dla React Native: komunikat o błędzie (user-friendly, nie techniczny), przycisk „Ponów”, link do pomocy lub czatu. Unikaj pustego View — użytkownik pomyśli, że aplikacja całkowicie się zepsuła i ją zamknie. Fallback powinien być wbudowany w ogólny design aplikacji.

Testowanie Error Boundary

Testuj każdy Error Boundary za pomocą React Testing Library lub React Native Testing Library. Stwórz komponent-trigger, który wyrzuca błąd przy renderze, i sprawdź, czy wyświetla się fallback UI. Do testów integracyjnych używaj storybook z różnymi stanami Error Boundary: normalnym, błędnym, stanem po resecie. Zautomatyzowane testowanie Boundary gwarantuje, że przy zmianie komponentu fallback UI nadal działa poprawnie w production. Pokrycie testami każdego Boundary powinno być obowiązkowym wymaganiem code review dla projektów React Native.

Często zadawane pytania

Dlaczego Error Boundary nie działa z komponentami funkcyjnymi?

React implementuje Error Boundary tylko przez komponenty klasowe, ponieważ wymagany jest dostęp do metod cyklu życia componentDidCatch i getDerivedStateFromError. Komponenty funkcyjne nie mają takich metod. Biblioteka react-error-boundary udostępnia gotowe opakowanie klasowe z API hooków dla wygody użytkowania.

Jak Error Boundary wpływa na wydajność?

Wpływ jest minimalny — Error Boundary dodaje sprawdzenie stanu przy każdym renderze drzewa potomnego. Porównanie state.hasError to operacja O(1) o stałej złożoności. Przy braku błędów overhead nie występuje. Tylko przy wystąpieniu błędu Boundary wykonuje dodatkowy render fallback UI.

Czy trzeba opakowywać każdy komponent w Error Boundary?

Nie, wystarczą 2–3 poziomy: korzeniowy Boundary dla całej aplikacji, ekranowy Boundary dla każdej gałęzi nawigacyjnej i lokalny Boundary dla krytycznych widgetów (formularz płatności, mapa, czat). Nadmierna liczba Boundary komplikuje architekturę bez znaczącej korzyści.

Jak Error Boundary współpracuje z Suspense w React 18+?

Error Boundary i Suspense są niezależne: Suspense przechwytuje ładowanie (pending Promise w React 18+), Error Boundary przechwytuje błędy renderowania. Można je łączyć: <ErrorBoundary><Suspense><Component /></Suspense></ErrorBoundary>. Suspense działa najpierw przy ładowaniu, Error Boundary — przy błędzie załadowanego komponentu.

Czym różni się Error Boundary od try-catch w React?

try-catch przechwytuje błędy w synchronicznym kodzie imperatywnym, ale nie może przechwycić błędów renderowania JSX. Error Boundary jest specjalnie zaprojektowany dla deklaratywnego UI: przechwytuje błędy w render, lifecycle-hookach i konstruktorach komponentów potomnych, czego try-catch nie może zrobić ze względu na specyfikę renderowania React.

Podsumowanie

  • Error Boundary — komponent React do przechwytywania błędów renderowania z wyświetlaniem fallback UI
  • ComponentDidCatch — metoda do logowania błędów, getDerivedStateFromError — do zarządzania stanem UI
  • React Native krytycznie potrzebuje Error Boundary do zapobiegania całkowitemu crashowi aplikacji
  • Ograniczenia — nie przechwytuje błędów asynchronicznych, błędów w event-handlerach, SSR i warstwie natywnej
  • react-error-boundary — gotowa biblioteka z API hooków do wygodnej integracji w projekcie
  • Poziomy opakowania — korzeniowy, ekranowy (zalecany) i lokalny dla krytycznych widgetów
  • Fallback UI powinien być znaczący: komunikat o błędzie, przycisk ponowienia, kontakt z pomocą

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również