Error Boundary είναι ένα component React που συλλαμβάνει σφάλματα JavaScript στο δέντρο των θυγατρικών component και εμφανίζει μια εφεδρική διεπαφή αντί για σελίδα crash. Στο πλαίσιο του React Native, αποτρέπει την πλήρη κατάρρευση της εφαρμογής σε μη θανατηφόρα σφάλματα απόδοσης. Σύμφωνα με το React Documentation, 2024, το error boundary συλλαμβάνει σφάλματα στις μεθόδους render, στα lifecycle-hooks και στους κατασκευαστές των θυγατρικών component, επιτρέποντας στην εφαρμογή να συνεχίσει. Στο React Native αυτό είναι ιδιαίτερα κρίσιμο, καθώς η εφαρμογή κινητού δεν επαναφορτώνεται με F5 — ο χρήστης χάνει ολόκληρη τη συνεδρία.
Κύρια σημεία
Error Boundary είναι ένας μηχανισμός React για σταδιακή υποβάθμιση σε σφάλματα απόδοσης. Εισήχθη στο React 16 (2017) ως component-περιτύλιγμα που υλοποιεί μία από τις δύο μεθόδους κύκλου ζωής: static getDerivedStateFromError ή componentDidCatch. Το Error Boundary επιτρέπει στον χρήστη να δει ένα κατανοητό μήνυμα αντί για λευκή οθόνη ή πλήρη κατάρρευση της εφαρμογής.
Πριν από το React 16, κάθε μη διαχειρισμένο σφάλμα στο render οδηγούσε σε κατάρρευση ολόκληρης της εφαρμογής με αποσυναρμολόγηση ολόκληρου του DOM δέντρου. Σε web εφαρμογές αυτό σήμαινε λευκή οθόνη, στο React Native — πλήρη κατάρρευση της εφαρμογής με επιστροφή στην Home Screen. Η ομάδα του React εισήγαγε το Error Boundary ως ανάλογο του catch-block για δηλωτικό UI, δανειζόμενη την έννοια από την προσέγγιση “άσε το να καταρρεύσει” στη γλώσσα Erlang.
Στο React Native, η απουσία Error Boundary σημαίνει πλήρη κατάρρευση της εφαρμογής σε κάθε σφάλμα απόδοσης. Ο χρήστης χάνει ολόκληρη την τρέχουσα συνεδρία χωρίς δυνατότητα ανάκτησης. Το Error Boundary στο React Native είναι κρίσιμο, καθώς οι εφαρμογές κινητού δεν επαναφορτώνονται όπως οι ιστοσελίδες — η συνεδρία χρήστη χάνεται ανεπανόρθωτα και ο χρήστης πρέπει να ξεκινήσει από την αρχή.
Error Boundary λειτουργεί στο επίπεδο του React δέντρου. Όταν ένα θυγατρικό component πετάει σφάλμα στο render ή lifecycle, το React δεν αποσυναρμολογεί ολόκληρο το δέντρο, αλλά μεταφέρει τον έλεγχο στο πλησιέστερο Error Boundary υψηλότερα στην ιεραρχία. Το Boundary καλεί το getDerivedStateFromError, ορίζει state.hasError = true και κάνει render το fallback UI αντί για τον κατεστραμμένο κλάδο component.
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("Συλλήφθηκε από το boundary:", error)
Crashlytics.recordException(error)
}
render() {
if (this.state.hasError) {
return this.props.fallback || <FallbackUI />
}
return this.props.children
}
}
getDerivedStateFromError ορίζει την κατάσταση για την απόδοση fallback UI — αυτή είναι μια στατική μέθοδος που καλείται στη φάση απόδοσης πριν από την επιβεβαίωση των αλλαγών. componentDidCatch εκτελείται στη φάση επιβεβαίωσης και προορίζεται για παρενέργειες: καταγραφή, αποστολή αναφορών crash στο Crashlytics, analytics. Δύο μέθοδοι μοιράζονται την ευθύνη μεταξύ διαχείρισης κατάστασης UI και παρενεργειών.
Για να δημιουργήσετε Error Boundary, πρέπει να υλοποιήσετε ένα class component με μεθόδους getDerivedStateFromError και/ή componentDidCatch. Τα functional components δεν μπορούν να είναι Error Boundary — το React υποστηρίζει αυτή τη λειτουργία μόνο για class components, καθώς απαιτείται πρόσβαση στις μεθόδους κύκλου ζωής. Στη βιβλιοθήκη react-error-boundary είναι διαθέσιμη μια έτοιμη υλοποίηση με hooks API για ευκολία.
// Παράδειγμα χρήσης Error Boundary στο React Native
import { ErrorBoundary } from "react-error-boundary"
const FallbackComponent = ({ error, resetError }: FallbackProps) => (
<View style={styles.container}>
<Text>Κάτι πήγε στραβά</Text>
<Text>{error.message}</Text>
<Button title="Δοκιμάστε ξανά" onPress={resetError} />
</View>
)
const App = () => (
<SafeAreaView>
<ErrorBoundary FallbackComponent={<FallbackComponent />}>
<UserProfile userId={"123"} />
</ErrorBoundary>
<BottomNavigation />
</SafeAreaView>
)
Επίπεδα περιτυλίγματος — Το Error Boundary μπορεί να τοποθετηθεί σε διαφορετικά επίπεδα της ιεραρχίας. Ένα καθολικό Boundary στη ρίζα της εφαρμογής θα εμφανίσει fallback UI σε κάθε σφάλμα, αλλά η πλοήγηση θα συνεχίσει να λειτουργεί. Πολλαπλά Boundary σε επίπεδο οθονών επιτρέπουν την απομόνωση σφαλμάτων: αν μία οθόνη χαλάσει, οι υπόλοιπες συνεχίζουν ανεξάρτητα. Το react-error-boundary απλοποιεί τον μηχανισμό Reset μέσω του useErrorBoundary hook, επιτρέποντας την επαναφορά κατάστασης χωρίς επαναφόρτωση. Για τυπικά έργα, το σχήμα με τρία επίπεδα Boundary θεωρείται βέλτιστο για εφαρμογές React Native.
Μετά την εμφάνιση σφάλματος, ο χρήστης μπορεί να πατήσει το κουμπί “Δοκιμάστε ξανά”, το οποίο επαναφέρει το hasError σε false και αναπαράγει το θυγατρικό δέντρο. Μηχανισμός Reset είναι σημαντικός για την αποκατάσταση της λειτουργικότητας της εφαρμογής χωρίς επαναφόρτωση. Στο react-error-boundary χρησιμοποιείται το onReset callback, το οποίο μπορεί να καθαρίσει την προσωρινή μνήμη, να ξαναζητήσει δεδομένα ή να ενημερώσει την κατάσταση ψηλότερα στο δέντρο.
Το Error Boundary δεν συλλαμβάνει ασύγχρονα σφάλματα — σφάλματα σε setTimeout, setInterval, Promise, async/await. Το React δεν μπορεί να συλλάβει σφάλματα εκτός του κύκλου απόδοσης και lifecycle-hooks, καθώς εκτελούνται σε άλλα συμφραζόμενα εκτέλεσης. Για ασύγχρονα σφάλματα απαιτείται ξεχωριστό try-catch στους handlers ή ένας καθολικός handler για το συμβάν unhandledrejection.
Σφάλματα σε onClick, onChange και άλλους event-handlers δεν συλλαμβάνονται από το Error Boundary, επειδή εκτελούνται εκτός της απόδοσης React. Διαχείριση σφαλμάτων για event-handlers πρέπει να γίνεται εντός του ίδιου του handler μέσω try-catch. Η βιβλιοθήκη react-error-boundary παρέχει το hook useErrorHandler για τη μεταφορά σφαλμάτων από event-handlers στο πλησιέστερο Boundary.
Το Error Boundary δεν λειτουργεί στην πλευρά διακομιστή σε Next.js ή Gatsby. Οι μέθοδοι getDerivedStateFromError και componentDidCatch δεν καλούνται σε SSR, καθώς οι μέθοδοι κύκλου ζωής είναι διαθέσιμες μόνο στο πρόγραμμα περιήγησης. Για σφάλματα διακομιστή απαιτείται ξεχωριστή στρατηγική: try-catch στο getServerSideProps, σελίδες fallback error.js (Next.js 13+) ή καθολικό middleware.
Στο React Native, το Error Boundary δεν αποτρέπει κατάρρευση σε επίπεδο εγγενών μονάδων. Εγγενής κατάρρευση (segfault, out-of-memory, εγγενής εξαίρεση) συμβαίνει σε επίπεδο Objective-C ή Java και δεν φτάνει στο επίπεδο JavaScript. Για εγγενείς καταρρεύσεις απαιτείται Crashlytics NDK (Android) ή KSCrash (iOS). Το Error Boundary προστατεύει μόνο το επίπεδο JavaScript της εφαρμογής React Native.
Τοποθετήστε το Error Boundary στα όρια σημασιολογικών μονάδων: ένα Boundary ανά οθόνη, ένα ανά widget τρίτου προγραμματιστή, ένα ανά σύνθετη φόρμα. Αυτό απομονώνει σφάλματα και επιτρέπει στον χρήστη να συνεχίσει την εργασία στα υπόλοιπα μέρη της εφαρμογής. Το ριζικό Boundary πρέπει πάντα να υπάρχει — για κρίσιμα σφάλματα σε κοινά component πλοήγησης ή providers. Κάθε Boundary είναι υπεύθυνο για το δικό του τμήμα διεπαφής και δεν επηρεάζει γειτονικά component κατά την εμφάνιση σφάλματος.
Πάντα μεταφέρετε το σφάλμα στο Crashlytics ή Sentry μέσω componentDidCatch. Προσθέστε συμφραζόμενα: όνομα οθόνης, userId, έκδοση εφαρμογής, παραμέτρους πλοήγησης. Στο Sentry είναι διαθέσιμα breadcrumbs — η ακολουθία ενεργειών χρήστη πριν από το σφάλμα. Για ανάλυση συχνότητας μη θανατηφόρων σφαλμάτων, χρησιμοποιήστε πίνακες εργαλείων Crashlytics με ομαδοποίηση ανά issue.
Μην χρησιμοποιείτε “κενό” fallback — δημιουργήστε ουσιαστική διεπαφή. Συνιστώμενο σύνολο για React Native: μήνυμα σφάλματος (φιλικό προς χρήστη, όχι τεχνικό), κουμπί “Δοκιμάστε ξανά”, σύνδεσμος υποστήριξης ή συνομιλίας. Αποφύγετε κενό View — ο χρήστης θα νομίσει ότι η εφαρμογή έχει καταρρεύσει εντελώς και θα την κλείσει. Το fallback πρέπει να ενσωματώνεται στον γενικό σχεδιασμό της εφαρμογής.
Δοκιμάστε κάθε Error Boundary με React Testing Library ή React Native Testing Library. Δημιουργήστε ένα component-ενεργοποιητή που πετάει σφάλμα κατά την απόδοση και ελέγξτε ότι εμφανίζεται το fallback UI. Για δοκιμές ολοκλήρωσης, χρησιμοποιήστε storybook με διαφορετικές καταστάσεις Error Boundary: κανονική, σφάλμα, κατάσταση μετά από επαναφορά. Η αυτοματοποιημένη δοκιμή Boundary εγγυάται ότι κατά την αλλαγή component, το fallback UI συνεχίζει να λειτουργεί σωστά στο production. Η κάλυψη δοκιμών κάθε Boundary πρέπει να είναι υποχρεωτική απαίτηση code review για έργα React Native.
Συχνές Ερωτήσεις
Το React υλοποιεί το Error Boundary μόνο μέσω class components, επειδή απαιτείται πρόσβαση στις μεθόδους κύκλου ζωής componentDidCatch και getDerivedStateFromError. Τα functional components δεν έχουν τέτοιες μεθόδους. Η βιβλιοθήκη react-error-boundary παρέχει ένα έτοιμο class περιτύλιγμα με hooks API για ευκολία χρήσης.
Η επίδραση είναι ελάχιστη — το Error Boundary προσθέτει έναν έλεγχο κατάστασης σε κάθε απόδοση του θυγατρικού δέντρου. Η σύγκριση state.hasError είναι μια λειτουργία O(1) με σταθερή πολυπλοκότητα. Απουσία σφαλμάτων, δεν υπάρχει επιβάρυνση. Μόνο κατά την εμφάνιση σφάλματος, το Boundary εκτελεί πρόσθετη απόδοση fallback UI.
Όχι, 2–3 επίπεδα είναι αρκετά: ριζικό Boundary για ολόκληρη την εφαρμογή, οθόνης Boundary για κάθε κλάδο πλοήγησης και τοπικό Boundary για κρίσιμα widgets (φόρμα πληρωμής, χάρτης, συνομιλία). Υπερβολικός αριθμός Boundary περιπλέκει την αρχιτεκτονική χωρίς σημαντικό όφελος.
Το Error Boundary και το Suspense είναι ανεξάρτητα: το Suspense συλλαμβάνει φόρτωση (pending Promise στο React 18+), το Error Boundary συλλαμβάνει σφάλματα απόδοσης. Μπορούν να συνδυαστούν: <ErrorBoundary><Suspense><Component /></Suspense></ErrorBoundary>. Το Suspense εκτελείται πρώτο κατά τη φόρτωση, το Error Boundary — κατά σφάλμα του φορτωμένου component.
Το try-catch συλλαμβάνει σφάλματα σε σύγχρονο προστακτικό κώδικα, αλλά δεν μπορεί να συλλάβει σφάλματα απόδοσης JSX. Το Error Boundary είναι ειδικά σχεδιασμένο για δηλωτικό UI: συλλαμβάνει σφάλματα στο render, lifecycle-hooks και κατασκευαστές θυγατρικών component, κάτι που το try-catch δεν μπορεί να κάνει λόγω των χαρακτηριστικών απόδοσης React.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης