错误边界
React 16 增加
- 防止某个组件的 UI 渲染错误导致整个应用崩溃
- 子组件发生 JS 的错误,有备用的渲染 UI
- 错误边界是一个组件,且只能用 class 组件来写
例子:
class Test extends React.Component{
render(){
return (
<div>{data.title}</div> // 这里出错
);
}
}
class Test extends React.Component{
render(){
return (
<p>Thins is content</p>
);
}
}
class App extentds React.Component{
render(){
return (
<div>
<Sub />
<Test />
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
整个应用是崩溃了,由 Test 组件引用一个未定义的 data 引起。
加上错误边界例子:
static getDerivedStateFromError(error) 生命周期函数
- 参数: 子组件抛出的错误
- 返回值: 新的 state
- 作用:获取捕获错误,修改错误状态
- 渲染备用的 UI
- 渲染阶段调用 、不允许出现副作用(主要是操作 DOM 或异步的操作 setTimeout 等)
componentDidCatch(error, info) 原型上的方法
边界错误组件捕获异常,并进行后续处理
- 参数:
- error 抛出的错误
- info 组件引发错误相关的信息 组件栈
- 作用:
- 错误信息获取
- 运行副作用
- 在组件抛出错误后调用
在开发环境中 componentDidCatch 会把错误向上冒泡到 window,
window.onerror = function(err){console.log(err);}
在生产环境是不行的 ```jsx / mistake 是人为的导致的失误, error 是客观引起偏离轨道的 bound -> bind 绑定 带子 线 bund -> ou ->o ->i ary 名词后缀 -> 边界 / class ErrorBoundary extends React.Component { state = { hasError: false, };static getDerivedStateFromError(error) { console.log(error); // data is not defined return { hasError: true }; }
componentDidCatch(error, info){
console.log(error, info); // data is not defined
// info: componentStack
}
render() { if (this.state.hasError) {
return <h1>This is Error UI</h1>;
}
return this.props.children; } }
class Test extends React.Component{ render(){ return (
class Sub extends React.Component{ render(){ return (
Thins is content
); } }class App extentds React.Component{ render(){ return (
无法捕获的场景
如果多个嵌套错误边界组件,则从最里层错误出发,向上冒泡出发捕获,
即错误边界公可以捕获其子组件的错误
组件栈追踪
显示出在哪里现在错误,从里到外一层一层地定位。
其依赖 @babel/plugin-transform-react-jsx-source
这个插件,仅用于开发环境。生产环境禁用。
try / catch
仅用于命令代码 (imperative code)
而错误边界是保留 React 的声明性质。错误边界是针对于渲染时的错误,所以事件处理函数的错误是不会被捕获的。
如果用对事件处理函数捕获错误,用 try / catch 即可。