Przejdź do głównej zawartości

10. Obsługa błędów w React

Obsługa błędów w React

Błędy w aplikacjach zdarzają się zawsze — sieć jest niedostępna, API zwraca 500, dane mają nieoczekiwany format. React Error Boundaries przechwytują błędy w drzewie komponentów. Wzorzec loading/error/data zapewnia przyjazny UI w każdym scenariuszu.

  1. Co to jest Error Boundary? — Komponent klasowy przechwytujący błędy w potomkach
  2. Co NIE jest obsługiwane przez Error Boundary? — Błędy asynchroniczne, event handlery, SSR
  3. Wzorzec loading/error/data? — Trzy stany komponentu przy pobieraniu danych
  4. Graceful degradation? — Aplikacja działa częściowo zamiast całkowicie się psuć
  1. Problem — błąd w jednym komponencie crashuje całą aplikację
  2. Error Boundary — komponent klasowy, componentDidCatch, getDerivedStateFromError
  3. Granularność — Error Boundary wokół krytycznych i niekrytycznych części
  4. Wzorzec loading/error/data — pełna obsługa stanów asynchronicznych
  5. try/catch w event handlerach — bo Error Boundary tego nie łapie

Schemat

Drzewo aplikacji z Error Boundary: Header (bez EB), Sidebar (z EB), MainContent (z EB), Footer (bez EB). Błąd w Sidebar nie psuje reszty aplikacji.

Przykład kodu JSX

Error Boundary komponent + użycie go wokół komponentu pobierającego dane z API.

  • Problem błędów bez obsługi
  • Wzorzec loading/error/data
  • Podstawowy Error Boundary

Forma: 10 slajdów, 10 minut

Ocena: 3.0
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
// Loguj błąd do serwisu monitorowania
console.error('Caught by ErrorBoundary:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return (
<div className="error-fallback">
<h2>Coś poszło nie tak</h2>
<p>{this.state.error?.message}</p>
<button onClick={() => this.setState({ hasError: false })}>
Spróbuj ponownie
</button>
</div>
);
}
return this.props.children;
}
}
// Użycie
function App() {
return (
<ErrorBoundary>
<UserProfile />
<ErrorBoundary>
<ProductList /> {/* Błąd tu nie psuje UserProfile */}
</ErrorBoundary>
</ErrorBoundary>
);
}
function DataComponent({ url }) {
const [state, setState] = useState({ loading: true, error: null, data: null });
useEffect(() => {
fetch(url)
.then(r => r.json())
.then(data => setState({ loading: false, error: null, data }))
.catch(error => setState({ loading: false, error: error.message, data: null }));
}, [url]);
if (state.loading) return <Spinner />;
if (state.error) return <ErrorMessage message={state.error} />;
return <DataDisplay data={state.data} />;
}

Pokaż błąd bez obsługi

Zacznijcie od demonstracji aplikacji BEZ Error Boundary — jeden błąd niszczy białą stronę. Potem pokażcie to samo z Error Boundary — aplikacja nadal działa.

Analogia

Error Boundary to jak bezpiecznik elektryczny — jeden zwarty obwód (komponent) nie wyłącza całego mieszkania (aplikacji).

Solidna aplikacja to odporna aplikacja!

Obsługa błędów odróżnia aplikacje produkcyjne od szkolnych. Po tej prezentacji klasa będzie pisać bardziej profesjonalny kod!