
Implémentation d'un Error Boundary (`componentDidCatch`, `getDerivedStateFromError`)
Guide détaillé pour créer un composant Error Boundary en React en utilisant les méthodes de cycle de vie componentDidCatch et getDerivedStateFromError.
Les méthodes de cycle de vie clés pour la capture d'erreurs
Comme mentionné précédemment, la capacité d'un composant React à agir comme une Error Boundary repose sur l'implémentation d'une ou deux méthodes spécifiques du cycle de vie des composants classe. Ces méthodes permettent au composant d'intercepter les erreurs provenant de ses descendants et de réagir en conséquence.
Il est essentiel de comprendre le rôle distinct de chacune de ces méthodes :
static getDerivedStateFromError(error): Son objectif principal est de permettre à l'Error Boundary de mettre à jour son propre état interne en réponse à une erreur, afin de pouvoir afficher une interface utilisateur de repli (fallback UI) lors du prochain rendu.componentDidCatch(error, errorInfo): Son objectif est d'effectuer des effets de bord (side effects) après qu'une erreur a été capturée, comme enregistrer (logger) les détails de l'erreur pour le débogage ou l'analyse.
Voyons comment implémenter chacune d'elles.
`static getDerivedStateFromError(error)` : Mettre à jour l'état pour le fallback
Cette méthode statique est déclenchée pendant la phase de "rendu" (render phase), juste après qu'un composant descendant a levé une erreur, mais avant que le DOM ne soit mis à jour. C'est la première étape du processus de capture d'erreur.
Signature : static getDerivedStateFromError(error)
- Elle reçoit l'objet d'erreur qui a été levé comme unique argument.
- Etant statique, elle n'a pas accès à l'instance du composant (pas de `this`).
- Elle doit retourner un objet qui sera utilisé pour mettre à jour l'état de l'Error Boundary, ou `null` pour n'indiquer aucune mise à jour d'état.
Rôle : Le but principal est de définir un indicateur dans l'état (par exemple, `hasError: true`) pour que la méthode `render` de l'Error Boundary sache qu'elle doit afficher l'UI de repli au lieu de ses enfants.
class MyErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Mettre à jour l'état pour indiquer qu'une erreur s'est produite
// Cela déclenchera un re-rendu avec l'UI de fallback
console.log('getDerivedStateFromError a intercepté:', error);
return { hasError: true };
}
render() {
if (this.state.hasError) {
// Rendu du fallback UI
return Quelque chose s'est mal passé.
;
}
// Rendu normal des enfants
return this.props.children;
}
}Il est important de noter que getDerivedStateFromError est appelée pendant la phase de rendu, donc les effets de bord (comme les appels API de logging) y sont interdits. C'est le rôle de `componentDidCatch`.
`componentDidCatch(error, errorInfo)` : Enregistrer les erreurs
Cette méthode est déclenchée pendant la phase de "commit", c'est-à-dire après que l'erreur a été capturée par getDerivedStateFromError et que le rendu (potentiellement avec l'UI de fallback) a été effectué et appliqué au DOM.
Signature : componentDidCatch(error, errorInfo)
error: Le même objet d'erreur que celui reçu pargetDerivedStateFromError.errorInfo: Un objet contenant des informations supplémentaires sur l'erreur, notamment la `componentStack` - une trace indiquant quel composant dans l'arbre a causé l'erreur. C'est extrêmement utile pour le débogage.- Contrairement à la méthode statique, celle-ci a accès à l'instance du composant via `this`.
Rôle : C'est l'endroit idéal pour effectuer des effets de bord liés à l'erreur, principalement pour l'enregistrer (la logger). Vous pouvez envoyer les informations d'erreur (`error` et `errorInfo.componentStack`) à votre service de suivi d'erreurs (Sentry, etc.) ou simplement les afficher dans la console en développement.
class MyErrorBoundaryWithLogging extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// Log l'erreur et la trace des composants
console.error("Error Boundary a intercepté une erreur:", error);
console.error("Trace des composants:", errorInfo.componentStack);
// Exemple d'envoi à un service de logging (à adapter)
// logErrorToService(error, errorInfo.componentStack);
}
render() {
if (this.state.hasError) {
return Erreur ! Vérifiez la console ou le service de logs.
;
}
return this.props.children;
}
}Important : N'utilisez pas `componentDidCatch` pour mettre à jour l'état afin de déclencher un rendu de fallback. C'est le rôle de `getDerivedStateFromError`. `componentDidCatch` s'exécute après le rendu.
Exemple complet d'Error Boundary
En combinant les deux méthodes, on obtient une Error Boundary complète qui affiche un fallback et logge l'erreur :
import React, { Component } from 'react';
class CompleteErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
error: null,
errorInfo: null
};
}
static getDerivedStateFromError(error) {
// Mettre à jour l'état pour le rendu du fallback
return { hasError: true, error: error };
}
componentDidCatch(error, errorInfo) {
// Enregistrer l'erreur et les informations
// Optionnel: stocker errorInfo dans l'état si on veut l'afficher
this.setState({ errorInfo: errorInfo });
console.error("ErrorBoundary Caught:", error, errorInfo);
// logErrorToService(error, errorInfo);
}
render() {
if (this.state.hasError) {
// Affichage du fallback UI
return (
Une erreur inattendue s'est produite.
Veuillez nous excuser pour la gêne occasionnée.
{/* Affichage conditionnel pour le développement */}
{process.env.NODE_ENV === 'development' && (
Détails de l'erreur (Dev)
{this.state.error && this.state.error.toString()}
{this.state.errorInfo && this.state.errorInfo.componentStack}
)}
);
}
// Si tout va bien, rendre les enfants
return this.props.children;
}
}
export default CompleteErrorBoundary;Cette implémentation fournit une base solide pour une Error Boundary : elle capture l'erreur, met à jour l'état pour afficher un fallback, et enregistre les détails de l'erreur pour analyse ultérieure.