我正在尝试在react中构造一个错误边界,如下所示:-
import React, { Component } from 'react';
type ErrorBoundaryProps = {
fallBackComponent: React.ReactElement;
resetState?: boolean;
}
type ErrorBoundaryState = {
hasError : boolean;
}
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
state = {hasError: false};
static getDerivedStateFromError( ){
return { hasError : true};
}
componentWillReceiveProps( newProps : ErrorBoundaryProps ){
if(newProps.resetState){
this.setState({hasError:false})
}
}
render(){
const {fallBackComponent, children} = this.props;
if(this.state.hasError){
return fallBackComponent;
}
return children;
}
}
使用“ resetState”道具的基本思想是,如果父道具改变,则强制错误边界尝试再次渲染子级。如果新道具仍然导致错误,它将返回到后备用户界面。因此,使用componentWillRecieveProps会强制在每次更改道具时hasError为false,并且错误边界会尝试呈现子组件。
调用它的父组件如下:-
import React, { useState } from 'react';
import {ErrorBoundary} from './ErrorBoundary';
const ErrorChild = ( { hasError } : {hasError : boolean}) => {
if(hasError){
throw new Error("Dummy error");
}
return <>Actual screen</>
}
const App: React.FC = () => {
const [error, setError] = useState(false);
return (
<div className="App">
<button onClick={() => setError((previousState) => !previousState)}>Toggle error</button>
<ErrorBoundary fallBackComponent={<>Fallback Screen</>} resetState>
<ErrorChild hasError={error} />
</ErrorBoundary>
</div>
);
}
export default App;
这基本上呈现了一个按钮,后面是实际的组件。单击按钮可切换错误状态,即孩子是否抛出错误。当“ resetState”道具为true时,我可以在“后备屏幕”和“实际屏幕”之间切换。当“ resetState”为false时,一旦呈现“后备屏幕”,则在再次切换时将不呈现“实际屏幕”。
如何在不使用componentWillRecieveProps的情况下实现相同的功能?
我尝试使用getDerivedStateFromProps,但事实证明,此函数在每次渲染之前都会调用,不仅是在props更改时调用,还可以在捕获错误并卸载整个DOM后有效地重置错误边界的状态。 。 其他技术建议使用由错误边界的父组件更改的“键”来强制重置错误边界。这对我不太感兴趣,因为我试图将其保留为可重复使用的组件,并且我不希望该组件的用户负责处理密钥更新。
还有其他方法可以实现吗?
我的基本要求是,如果对孩子的道具的更改不再引起错误,则错误边界应向孩子显示。