Error Boundary est un composant React qui intercepte les erreurs JavaScript dans son arborescence de composants enfants et affiche une interface de secours au lieu d’une page d’erreur. Dans le contexte de React Native, il empêche un plantage complet de l’application lors d’erreurs de rendu non fatales. Selon la Documentation React, 2024, error boundary capture les erreurs dans les méthodes render, les hooks du cycle de vie et les constructeurs des composants enfants, permettant à l’application de continuer à fonctionner. Dans React Native, c’est particulièrement critique car une application mobile ne peut pas être rechargée avec F5 — l’utilisateur perd toute sa session.
Points clés
Error Boundary est un mécanisme React pour la dégradation progressive lors d’erreurs de rendu. Introduit dans React 16 (2017) comme composant encapsulant implémentant l’une des deux méthodes du cycle de vie : static getDerivedStateFromError ou componentDidCatch. Error Boundary permet d’afficher à l’utilisateur un message pertinent au lieu d’un écran blanc vide ou d’un plantage complet de l’application.
Avant React 16, toute erreur non traitée dans render provoquait un plantage complet de l’application avec démontage de tout l’arbre DOM. Dans les applications web, cela signifiait un écran blanc vide ; dans React Native, un plantage complet avec retour à l’écran d’accueil. L’équipe React a introduit Error Boundary comme un analogue du bloc catch pour l’UI déclarative, empruntant le concept de l’approche «let it crash» du langage Erlang.
Dans React Native, l’absence d’Error Boundary signifie un plantage complet de l’application lors de toute erreur de rendu. L’utilisateur perd toute sa session actuelle sans possibilité de récupération. Error Boundary dans React Native est crucial car les applications mobiles ne peuvent pas être rechargées comme des pages web — la session utilisateur est irrémédiablement perdue et l’utilisateur doit tout recommencer depuis le début.
Error Boundary fonctionne au niveau de l’arbre React. Lorsqu’un composant enfant lève une erreur dans render ou le cycle de vie, React ne démonte pas tout l’arbre mais transmet le contrôle à l’Error Boundary le plus proche dans la hiérarchie. Le Boundary appelle getDerivedStateFromError, définit state.hasError = true et rend l’interface de secours à la place de la branche de composants cassée.
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("Caught by boundary:", error)
Crashlytics.recordException(error)
}
render() {
if (this.state.hasError) {
return this.props.fallback || <FallbackUI />
}
return this.props.children
}
}
getDerivedStateFromError définit l’état pour le rendu de l’interface de secours — c’est une méthode statique appelée pendant la phase de rendu avant la validation des modifications. componentDidCatch s’exécute pendant la phase de validation et est destiné aux effets secondaires : journalisation, envoi de rapports de plantage à Crashlytics, analytique. Les deux méthodes séparent la responsabilité entre la gestion de l’état de l’UI et les effets secondaires.
Pour créer un Error Boundary, vous devez implémenter un composant de classe avec les méthodes getDerivedStateFromError et/ou componentDidCatch. Les composants fonctionnels ne peuvent pas être Error Boundary — React ne prend en charge cette fonctionnalité que pour les composants de classe car l’accès aux méthodes du cycle de vie est nécessaire. La bibliothèque react-error-boundary fournit une implémentation prête avec une API basée sur les hooks pour plus de commodité.
// Exemple d’utilisation d’Error Boundary dans React Native
import { ErrorBoundary } from "react-error-boundary"
const FallbackComponent = ({ error, resetError }: FallbackProps) => (
<View style={styles.container}>
<Text>Quelque chose s’est mal passé</Text>
<Text>{error.message}</Text>
<Button title="Réessayer" onPress={resetError} />
</View>
)
const App = () => (
<SafeAreaView>
<ErrorBoundary FallbackComponent={<FallbackComponent />}>
<UserProfile userId={"123"} />
</ErrorBoundary>
<BottomNavigation />
</SafeAreaView>
)
Niveaux d’encapsulation — Error Boundary peut être placé à différents niveaux de la hiérarchie. Un Boundary global à la racine de l’application affichera une interface de secours en cas d’erreur, mais la navigation sera conservée. Plusieurs Boundaries au niveau de l’écran permettent d’isoler les erreurs : si un écran se casse, les autres continuent de fonctionner indépendamment. react-error-boundary simplifie le mécanisme de réinitialisation via le hook useErrorBoundary, permettant de réinitialiser l’état sans rechargement. Pour les projets typiques, un schéma à trois niveaux de Boundary est considéré comme optimal pour les applications React Native.
Après une erreur, l’utilisateur peut cliquer sur le bouton « Réessayer », qui réinitialise hasError à false et réaffiche l’arborescence enfant. Le mécanisme de réinitialisation est important pour restaurer les fonctionnalités de l’application sans rechargement. Dans react-error-boundary, le callback onReset est utilisé, qui peut vider le cache, re-demander des données ou mettre à jour l’état plus haut dans l’arbre.
Error Boundary ne capture pas les erreurs asynchrones — erreurs dans setTimeout, setInterval, Promise, async/await. React ne peut pas intercepter les erreurs en dehors du cycle de rendu et des hooks du cycle de vie car elles sont exécutées dans des contextes d’exécution différents. Pour les erreurs asynchrones, un try-catch séparé dans les gestionnaires ou un gestionnaire global d’événement unhandledrejection est nécessaire.
Les erreurs dans onClick, onChange et autres gestionnaires d’événements ne sont pas capturées par Error Boundary car elles s’exécutent en dehors du rendu React. La gestion des erreurs pour les gestionnaires d’événements doit être effectuée à l’intérieur du gestionnaire lui-même avec try-catch. La bibliothèque react-error-boundary fournit le hook useErrorHandler pour lancer des erreurs des gestionnaires d’événements vers le Boundary le plus proche.
Error Boundary ne fonctionne pas côté serveur dans Next.js ou Gatsby. Les méthodes getDerivedStateFromError et componentDidCatch ne sont pas appelées pendant le SSR car les méthodes du cycle de vie ne sont disponibles que dans le navigateur. Pour les erreurs serveur, une stratégie séparée est nécessaire : try-catch dans getServerSideProps, pages de secours error.js (Next.js 13+), ou middleware global.
Dans React Native, Error Boundary n’empêche pas les plantages au niveau des modules natifs. Un plantage natif (segfault, dépassement de mémoire, exception native) se produit au niveau Objective-C ou Java et n’atteint pas la couche JavaScript. Pour les plantages natifs, Crashlytics NDK (Android) ou KSCrash (iOS) est nécessaire. Error Boundary ne protège que la couche JavaScript d’une application React Native.
Placez Error Boundary aux limites des modules logiques : un Boundary par écran, un par widget tiers, un par formulaire complexe. Cela isole les erreurs et permet à l’utilisateur de continuer à travailler dans d’autres parties de l’application. Un Boundary racine doit toujours être présent — pour les erreurs critiques dans les composants de navigation communs ou les fournisseurs. Chaque Boundary est responsable de son propre fragment d’interface et n’affecte pas les composants voisins en cas d’erreur.
Transmettez toujours l’erreur à Crashlytics ou Sentry via componentDidCatch. Ajoutez du contexte : nom de l’écran, userId, version de l’application, paramètres de navigation. Dans Sentry, les breadcrumbs sont disponibles — une séquence d’actions utilisateur ayant conduit à l’erreur. Pour analyser la fréquence des erreurs non fatales, utilisez les tableaux de bord Crashlytics avec regroupement par issue.
N’utilisez pas un fallback nu — créez une interface pertinente. Ensemble recommandé pour React Native : message d’erreur (convivial, non technique), un bouton « Réessayer », un lien vers le support ou le chat. Évitez une vue vide — l’utilisateur pensera que l’application a complètement planté et la fermera. Le fallback doit être intégré dans la conception globale de l’application.
Testez chaque Error Boundary avec React Testing Library ou React Native Testing Library. Créez un composant déclencheur qui lève une erreur lors du rendu et vérifiez que l’interface de secours s’affiche. Pour les tests d’intégration, utilisez storybook avec différents états d’Error Boundary : normal, erreur, état après réinitialisation. Les tests automatisés de Boundary garantissent que lorsque le composant change, l’interface de secours continue de fonctionner correctement en production. La couverture de test pour chaque Boundary devrait être une exigence obligatoire de révision de code pour les projets React Native.
Questions fréquentes
React implémente Error Boundary uniquement via des composants de classe car l’accès aux méthodes du cycle de vie componentDidCatch et getDerivedStateFromError est requis. Les composants fonctionnels n’ont pas de telles méthodes. La bibliothèque react-error-boundary fournit un encapsuleur de classe prêt avec une API basée sur les hooks pour faciliter l’utilisation.
L’impact est minime — Error Boundary ajoute une vérification d’état à chaque rendu de l’arborescence enfant. La comparaison de state.hasError est une opération O(1) avec une complexité constante. En l’absence d’erreurs, il n’y a pas de surcharge. Ce n’est que lorsqu’une erreur se produit que le Boundary effectue un rendu supplémentaire de l’interface de secours.
Non, 2–3 niveaux suffisent : un Boundary racine pour toute l’application, un Boundary d’écran pour chaque branche de navigation et un Boundary local pour les widgets critiques (formulaire de paiement, carte, chat). L’utilisation excessive de Boundaries complexifie l’architecture sans bénéfice significatif.
Error Boundary et Suspense sont indépendants : Suspense capture le chargement (Promise en attente dans React 18+), Error Boundary capture les erreurs de rendu. Ils peuvent être combinés : <ErrorBoundary><Suspense><Component /></Suspense></ErrorBoundary>. Suspense se déclenche en premier lors du chargement, Error Boundary se déclenche lors d’une erreur du composant chargé.
try-catch capture les erreurs dans le code impératif synchrone mais ne peut pas intercepter les erreurs de rendu JSX. Error Boundary est spécifiquement conçu pour l’UI déclarative : il intercepte les erreurs dans render, les hooks du cycle de vie et les constructeurs des composants enfants, ce que try-catch ne peut pas faire en raison des spécificités du rendu React.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi