53 lines
1.4 KiB
TypeScript
53 lines
1.4 KiB
TypeScript
import type { ReactElement, ReactNode } from 'react';
|
|
import { Component } from 'react';
|
|
|
|
export interface IErrorFallbackProps {
|
|
// Ошибка, возникшая в одном из дочерних компонентов
|
|
error: unknown;
|
|
// Перезагрузить компонент.
|
|
reload(): void;
|
|
}
|
|
|
|
export interface IErrorBoundaryProps {
|
|
// Функция для рендера ошибки, произошедшей в процессе рендера дочернего компонента.
|
|
errorFallback(props: IErrorFallbackProps): ReactElement;
|
|
// Событие перезагрузки компонента.
|
|
onReload?(): void;
|
|
children: ReactNode;
|
|
}
|
|
|
|
export type IErrorBoundaryState =
|
|
| {
|
|
status: 'error';
|
|
error: unknown;
|
|
}
|
|
| { status: 'ok' };
|
|
|
|
export class ErrorBoundary extends Component<IErrorBoundaryProps, IErrorBoundaryState> {
|
|
static getDerivedStateFromError(error: unknown): IErrorBoundaryState {
|
|
return { status: 'error', error };
|
|
}
|
|
|
|
state: IErrorBoundaryState = {
|
|
status: 'ok',
|
|
};
|
|
|
|
reload(): void {
|
|
this.setState({ status: 'ok' });
|
|
this.props.onReload?.();
|
|
}
|
|
|
|
render() {
|
|
if (this.state.status === 'error') {
|
|
const { errorFallback } = this.props;
|
|
|
|
return errorFallback({
|
|
error: this.state.error,
|
|
reload: () => this.reload(),
|
|
});
|
|
}
|
|
|
|
return this.props.children;
|
|
}
|
|
}
|