import { Component , ComponentType , ErrorInfo , FunctionComponent , isValidElement , PropsWithChildren , PropsWithRef , ReactElement , useState , } from 'react' ; const changedArray = ( a = [ ] , b = [ ] ) => a . length !== b . length || a . some ( ( item , index ) => ! Object . is ( item , b [ index ] ) ) ; interface FallbackProps { error : Error ; resetErrorBoundary : ( ... args : Array < unknown > ) => void ; } interface ErrorBoundaryPropsWithComponent { onResetKeysChange ? : ( prevResetKeys : Array < unknown > | undefined , resetKeys : Array < unknown > | undefined ) => void ; onReset ? : ( ... args : Array < unknown > ) => void ; onError ? : ( error : Error , info : { componentStack : string ; } ) => void ; resetKeys ? : Array < unknown > ; fallback ? : never ; FallbackComponent : ComponentType < FallbackProps > ; fallbackRender ? : never ; } declare function FallbackRender ( props ) ; interface ErrorBoundaryPropsWithRender { onResetKeysChange ? : ( prevResetKeys : Array < unknown > | undefined , resetKeys : Array < unknown > | undefined ) => void ; onReset ? : ( ... args : Array < unknown > ) => void ; onError ? : ( error : Error , info : { componentStack : string ; } ) => void ; resetKeys ? : Array < unknown > ; fallback ? : never ; FallbackComponent ? : never ; fallbackRender : typeof FallbackRender ; } interface ErrorBoundaryPropsWithFallback { onResetKeysChange ? : ( prevResetKeys : Array < unknown > | undefined , resetKeys : Array < unknown > | undefined ) => void ; onReset ? : ( ... args : Array < unknown > ) => void ; onError ? : ( error : Error , info : { componentStack : string ; } ) => void ; resetKeys ? : Array < unknown > ; fallback : ReactElement < unknown , string | FunctionComponent | typeof Component > | null ; FallbackComponent ? : never ; fallbackRender ? : never ; } type ErrorBoundaryProps = ErrorBoundaryPropsWithFallback | ErrorBoundaryPropsWithComponent | ErrorBoundaryPropsWithRender ; type ErrorBoundaryState = { error : Error | null ; } ; const initialState = { error : null } ; class ErrorBoundary extends Component < PropsWithRef < PropsWithChildren < ErrorBoundaryProps > > , ErrorBoundaryState > { static getDerivedStateFromError ( error ) { return { error } ; } state = initialState ; updatedWithError = false ; resetErrorBoundary = ( ... args ) => { this . props . onReset ?. ( ... args ) ; this . reset ( ) ; } ; reset ( ) { this . updatedWithError = false ; this . setState ( initialState ) ; } componentDidCatch ( error , info ) { this . props . onError ?. ( error , info ) ; } componentDidMount ( ) { const { error } = this . state ; if ( error !== null ) { this . updatedWithError = true ; } } componentDidUpdate ( prevProps ) { const { error } = this . state ; const { resetKeys } = this . props ; if ( error !== null && ! this . updatedWithError ) { this . updatedWithError = true ; return ; } if ( error !== null && changedArray ( prevProps . resetKeys , resetKeys ) ) { this . props . onResetKeysChange ?. ( prevProps . resetKeys , resetKeys ) ; this . reset ( ) ; } } render ( ) { const { error } = this . state ; const { fallbackRender , FallbackComponent , fallback } = this . props ; if ( error !== null ) { const props = { error , resetErrorBoundary : this . resetErrorBoundary , } ; if ( isValidElement ( fallback ) ) { return fallback ; } else if ( typeof fallbackRender === 'function' ) { return fallbackRender ( props ) ; } else if ( FallbackComponent ) { return < FallbackComponent { ... props } / > ; } else { throw new Error ( 'react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop' ) ; } } return this . props . children ; } } function useErrorHandler ( givenError ? ) { const [ error , setError ] = useState < unknown > ( null ) ; if ( givenError != null ) throw givenError ; if ( error != null ) throw error ; return setError ; } export { ErrorBoundary , useErrorHandler } ; export type { FallbackProps } ;