1import { Component, type ReactNode } from "react";
2
3interface RenderErrorBoundaryProps {
4 readonly children: ReactNode;
5 readonly fallback: ReactNode;
6 readonly resetKeys?: ReadonlyArray<unknown>;
7}
8
9interface RenderErrorBoundaryState {
10 readonly failed: boolean;
11 readonly resetKeys?: ReadonlyArray<unknown> | undefined;
12}
13
14export class RenderErrorBoundary extends Component<
15 RenderErrorBoundaryProps,
16 RenderErrorBoundaryState
17> {
18 override state = { failed: false, resetKeys: this.props.resetKeys };
19
20 static getDerivedStateFromProps(
21 { resetKeys }: RenderErrorBoundaryProps,
22 state: RenderErrorBoundaryState,
23 ) {
24 if (
25 resetKeys?.length !== state.resetKeys?.length ||
26 resetKeys?.some((key, index) => !Object.is(key, state.resetKeys?.[index]))
27 ) {
28 return { failed: false, resetKeys };
29 }
30 return null;
31 }
32
33 static getDerivedStateFromError() {
34 return { failed: true };
35 }
36
37 override render() {
38 return this.state.failed ? this.props.fallback : this.props.children;
39 }
40}