注意点:
- 类组件是可以和函数式组件混合写的!!!
- getDerivedStateFromError是静态的,避免副作用,如果想将错误上报到服务器,则去
componentDidCatch
里去处理。 - getDerivedStateFromError直接返回
{ hasError: true, errorInfo: error }
,即可修改当前错误边界组件的 state,从而达到控制显示内容的效果。 - 错误边界不捕捉以下错误。
- 事件处理程序(了解更多
- 异步代码(例如 setTimeout 或 requestAnimationFrame 回调)。
- 服务器端的渲染
- 在错误边界本身(而不是其子女)中抛出的错误
import { Store } from 'antd/es/form/interface';
import React from 'react';
function Bomb({ username }) {
console.log('username', username);
if (username === 'bomb') {
throw new Error('💥 CABOOM 💥');
}
return <div>{`Hi ${username}`}</div>;
}
import { Component } from 'react';
class MyErrorBoundary extends Component {
constructor(props: any) {
super(props);
this.state = {
hasError: false,
errorInfo: null,
};
}
componentDidMount(): void {
console.log('this.props', this.props);
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {
// 在这里可以做错误收集、打印、掉接口上报
console.log(
'MyErrorBoundary _________ componentDidCatch error,errorInfo',
error,
errorInfo,
);
}
static getDerivedStateFromError(error: Error) {
console.log('MyErrorBoundary _________ getDerivedStateFromError error,errorInfo', error);
return { hasError: true, errorInfo: error };
}
render() {
const { hasError, errorInfo } = this.state;
return (
<div style={{ border: '2px solid pink' }}>
这里是我自定义的错误边界
{hasError ? (
<div>
<h2>Something went wrong!!!!!</h2>
<pre style={{ color: 'pink' }}>{errorInfo.message}</pre>
</div>
) : (
this.props.children
)}
</div>
);
}
}
function App() {
const [username, setUsername] = React.useState('');
const usernameRef = React.useRef(null);
return (
<div>
<label>
{`Username (don't type "bomb"): `}
<input
placeholder={`type "bomb"`}
value={username}
onChange={(e) => setUsername(e.target.value)}
ref={usernameRef}
/>
</label>
<div>
<MyErrorBoundary>
<Bomb username={username} />
</MyErrorBoundary>
</div>
</div>
);
}
export default App;