一. 理解
- 部分 UI 的 JavaScript 错误不应该导致整个应用崩溃,为了解决这个问题,React 16 引入了一个新的概念 —— 错误边界。
- 错误边界是一种 React 组件,这种组件可以捕获发生在其子组件树任何位置的 JavaScript 错误,并打印这些错误,同时展示降级 UI,而并不会渲染那些发生崩溃的子组件树。错误边界可以捕获发生在整个子组件树的渲染期间、生命周期方法以及构造函数中的错误。
- 简单理解:用来捕获后代组件错误,渲染出备用页面。
- 错误边界的工作方式类似于 JavaScript 的
catch {}
,不同的地方在于错误边界只针对 React 组件。只有 class 组件才可以成为错误边界组件。大多数情况下, 你只需要声明一次错误边界组件, 并在整个应用中使用它。 - 错误边界仅可以捕获其子组件的错误,它无法捕获其自身的错误。如果一个错误边界无法渲染错误信息,则错误会冒泡至最近的上层错误边界,这也类似于 JavaScript 中
catch {}
的工作机制。
二. 使用
1. 使用方式
使用
static getDerivedStateFromError()
渲染备用 UI ,使用componentDidCatch()
打印错误信息。
state = { hasError: "" };
static getDerivedStateFromError(error) {
console.log(error);
// 在render之前触发,返回新的state
return {
hasError: true,
};
}
componentDidCatch(error, info) {
console.log(error, info);
}
2. 使用案例
Parent.jsx
(父组件)不过子组件的错误,渲染出备用提示页面
import React, { Component } from "react"; import Child from "./Child"; export default class Parent extends Component { state = { hasError: "" }; // 如果该组件的子组件出现报错时,会触发 getDerivedStateFromError 生命周期钩子,并携带错误信息 static getDerivedStateFromError(error) { return { hasError: error }; } // 如果该组件的子组件出现报错时,捕捉抛出的异常 componentDidCatch(error, info) { console.log("渲染组件时,发生错误!", error, info); } render() { return ( <div> <h2>Parent组件</h2> {this.state.hasError ? ( //也可以是组件页面 <h2>当前网络不稳定,请稍后重试!</h2> ) : ( <Child /> )} </div> ); } }
Child.jsx
(子组件)正确情况 persons 参数是一个
[{id:0,name:"小明",age:18}]
数组形式,当前渲染的 persons 参数是一个字符串形式,页面渲染发生错误。import React, { Component } from "react"; export default class Child extends Component { state = { persons: "abc", // persons: [ // { // id: 1, // name: "小明", // age: 18, // }, // { // id: 2, // name: "小丽", // age: 19, // }, // { // id: 3, // name: "小亮", // age: 20, // }, // ], }; render() { return ( <div> <h2>Child组件</h2> {this.state.persons.map((person) => { return ( <div key={person.id}> {person.name}——{person.age} </div> ); })} </div> ); } }