如果渲染的子组件不可信(比如来源于第三方),怎么保证程序的正常运行?
本文主要是React生命周期componentDidCatch的应用。
UntrustedComponent.js不可信组件代码如下:
import {useState} from 'react';
export default function UntrustedComponent() {
const [list, setList] = useState([1,2,3])
// 为模拟错误,此处故意赋值为null
function onClick() {
setList(null)
}
return (
<div>
<h3>第三方组件</h3>
<button onClick={onClick}>点击模拟触发错误</button>
<ul>
{list.map(item => <li key={item}>{item}</li>)}
</ul>
</div>
)
}
点击模拟触发错误按钮,将会在render期间抛出错误。
App.js未使用componentDidCatch时的代码如下:
import UntrustedComponent from './components/UntrustedComponent';
function App() {
return (
<div>
<h1>我的网站</h1>
<UntrustedComponent />
</div>
);
}
export default App;
此时,当子组件UntrustedComponent组件触发错误时,将导致整个App无法渲染(也就是白屏)。所以当子组件不可信时,应捕获错误,以防整个App都受到影响。
ErrorBoundary.js错误捕获组件 如下:
import React from 'react'
export default class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// 更新 state 使下一次渲染可以显示错误提示
return { hasError: true };
}
componentDidCatch(error, info) {
// Example "componentStack":
// at UntrustedComponent
// at ErrorBoundary
// at div
// at App
console.log(info.componentStack);
}
render() {
if (this.state.hasError) {
return <div>子组件渲染错误。</div>;
}
return this.props.children;
}
}
App.js使用ErrorBoundary时的代码如下:
import ErrorBoundary from './components/ErrorBoundary';
import UntrustedComponent from './components/UntrustedComponent';
function App() {
return (
<div className='app'>
<h1>我的网站</h1>
<ErrorBoundary>
<UntrustedComponent />
</ErrorBoundary>
</div>
);
}
export default App;
此时,当子组件UntrustedComponent组件触发错误时,错误将被捕获,效果如下:
错误日志如下:
at UntrustedComponent (http://localhost:3001/static/js/main.chunk.js:319:81)
at ErrorBoundary (http://localhost:3001/main.7261ff8cf03a4eb4d481.hot-update.js:25:5)
at div
at App