默认情况下,若一个组件在渲染期间(render)发生错误,会导致整个组件树全部被卸载
import React from 'react'
import ErrorBound from "./components/common/ErrorBound"
function Comp1() {
return <div style={{
width: "90%",
height: 500,
border: "2px solid"
}}>
<h1>Comp1</h1>
<Comp2 />
</div>
}
function Comp2(props) {
return <div style={{
width: "70%",
height: "70%",
border: "2px solid"
}}>
<h1>{this.state.name}</h1>
</div>
}
function Comp3() {
return <div style={{
width: "90%",
height: 500,
border: "2px solid"
}}>
<h1>Comp3</h1>
</div>
}
export default function App() {
return <div>
<Comp1 />
<Comp3 />
</div>
}
在上面组件中,Comp2使用了未定义的state.name,导致组件错误,从而影响到整个react无法正常显示。
那么我们有没有办法避免这种现象呢?
错误边界:是一个组件,该组件会捕获到渲染期间(render)子组件发生的错误,并有能力阻止错误继续传播
//ErrorBound
import React, { PureComponent } from 'react'
export default class ErrorBound extends PureComponent {
state = {
hasError: false
}
static getDerivedStateFromError(error) {
console.log("发生错误了");
return {
hasError: true
}
}
render() {
if (this.state.hasError) {
return <h1>出现错误了!</h1>
}
return this.props.children
}
}
import React from 'react'
import ErrorBound from "./components/common/ErrorBound"
function Comp1() {
return <div style={{
width: "90%",
height: 500,
border: "2px solid"
}}>
<h1>Comp1</h1>
<Comp2 />
</div>
}
function Comp2(props) {
return <div style={{
width: "70%",
height: "70%",
border: "2px solid"
}}>
<h1>{this.state.name}</h1>
</div>
}
function Comp3() {
return <div style={{
width: "90%",
height: 500,
border: "2px solid"
}}>
<h1>Comp3</h1>
</div>
}
export default function App() {
return <div>
<ErrorBound>
<Comp1 />
</ErrorBound>
<Comp3 />
</div>
}
此时我们创建一个组件,使用getDerivedStateFromError
静态函数,渲染子组件的过程中,一旦发生错误之后,在更新页面之前会执行该函数,函数中我们改变state的值,最后通过判断state的值动态判断是否有错误。
注意:getDerivedStateFromError
此外还有一个函数componentDidCatch
import React, { PureComponent } from 'react'
export default class ErrorBound extends PureComponent {
state = {
hasError: false
}
static getDerivedStateFromError(error) {
console.log("发生错误了");
return {
hasError: true
}
}
componentDidCatch(error, info) {
console.log("记录错误信息");
}
render() {
if (this.state.hasError) {
return <h1>出现错误了!</h1>
}
return this.props.children
}
}
细节
某些错误,错误边界组件无法捕获
render() {
setTimeout(() => {
throw new Error("asfasdfasf");
}, 1000);
if (this.state.hasError) {
return <h1>出现错误了!</h1>
}
return this.props.children
}
}
function Comp2() {
return <div style={{
width: "70%",
height: "70%",
border: "2px solid"
}}>
<h1 onClick={()=>{
throw new Error("点击时发生的错误")
}}>Comp2</h1>
</div>
}
总结:仅处理渲染子组件期间的同步错误
博主开始运营自己的公众号啦,感兴趣的可以关注“飞羽逐星”微信公众号哦,拿起手机就能阅读感兴趣的博客啦!