Mise à jour d'avril 2020:
Le problème semble être résolu dans la dernière React 16.13.1, voir cet exemple de bac à sable . Merci à @abernier pour l'avoir signalé.
J'ai fait quelques recherches et j'ai trouvé une différence importante:
React ne traite pas les erreurs des méthodes de cycle de vie asynchrones.
Donc, si vous écrivez quelque chose comme ceci:
componentDidMount()
{
throw new Error('I crashed!');
}
alors votre erreur sera interceptée par la limite d'erreur , et vous pouvez la traiter et afficher un message gracieux.
Si nous changeons le code comme ceci:
async componentDidMount()
{
throw new Error('I crashed!');
}
ce qui équivaut à ceci:
componentDidMount()
{
return Promise.reject(new Error('I crashed!'));
}
alors votre erreur sera avalée en silence . Honte à toi, réagis ...
Alors, comment traitons-nous les erreurs? Le seul moyen semble être une capture explicite comme celle-ci:
async componentDidMount()
{
try
{
await myAsyncFunction();
}
catch(error)
{
//...
}
}
ou comme ça:
componentDidMount()
{
myAsyncFunction()
.catch(()=>
{
//...
});
}
Si nous voulons toujours que notre erreur atteigne la limite d'erreur, je peux penser à l'astuce suivante:
- Attrapez l'erreur, faites changer l'état du composant par le gestionnaire d'erreurs
- Si l'état indique une erreur, supprimez-la de la
render
méthode
Exemple:
class BuggyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { error: null };
}
buggyAsyncfunction(){ return Promise.reject(new Error('I crashed async!'));}
async componentDidMount() {
try
{
await this.buggyAsyncfunction();
}
catch(error)
{
this.setState({error: error});
}
}
render() {
if(this.state.error)
throw this.state.error;
return <h1>I am OK</h1>;
}
}