Here is my current attempt on how to properly type a React ErrorBoundary
class component in Typescript:
import React from "react";
import ErrorPage from "./ErrorPage";
import type { Store } from "redux"; // I'M PASSING THE REDUX STORE AS A CUSTOM PROP
interface Props {
store: Store // THIS IS A CUSTOM PROP THAT I'M PASSING
}
interface State { // IS THIS THE CORRECT TYPE FOR THE state ?
hasError: boolean
}
class ErrorBoundary extends React.Component<Props,State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error): State {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, errorInfo: React.ErrorInfo): void {
// You can also log the error to an error reporting service
// logErrorToMyService(error, errorInfo);
console.log("error: " + error);
console.log("errorInfo: " + JSON.stringify(errorInfo));
console.log("componentStack: " + errorInfo.componentStack);
}
render(): React.ReactNode {
if (this.state.hasError) {
// You can render any custom fallback UI
return(
<ErrorPage
message={"Something went wrong..."}
/>
);
}
return this.props.children;
}
}
export default ErrorBoundary;
This question is about the types for this ErrorBoundary
class component. I'm breaking it into parts to make it easier.
PART A: Types for props and state
Is what I'm doing right?
interface Props {
store: Store // THIS IS A CUSTOM PROP THAT I'M PASSING
}
interface State { // IS THIS THE CORRECT TYPE FOR THE state ?
hasError: boolean
}
class ErrorBoundary extends React.Component<Props,State> {}
PART B: getDerivedStateFromError(error)
What type should I choose for the error
parameter? The return type should be the State
type, right?
static getDerivedStateFromError(error): State {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
PART C: componentDidCatch(error, errorInfo: React.React.ErrorInfo)
What type should I choose for the error
parameter? For the errorInfo
, React does have a ErrorInfo
type that seems to be correct. Is it? The return type should be void
, correct?
componentDidCatch(error, errorInfo: React.ErrorInfo): void {
console.log("error: " + error);
console.log("errorInfo: " + JSON.stringify(errorInfo));
console.log("componentStack: " + errorInfo.componentStack);
}
PART D: the render() method
Should the return type be ReactNode
?
render(): React.ReactNode {
if (this.state.hasError) {
// You can render any custom fallback UI
return(
<ErrorPage
message={"Something went wrong..."}
/>
);
}
return this.props.children;
}
You will get all your answers in the file index.d.ts
from @types/react
. If you are using an IDE like VSCode, you can Ctrl+click on a type to directly go to its definition.
Here is the precise answers to your questions, but before, let me advise you to prefer using react hooks
instead of classes.
EDIT by OP: I never use class components, always prefer function and hooks, but from React docs on Error Boundaries:
Error boundaries work like a JavaScript catch {} block, but for components. Only class components can be error boundaries.
The lines I give are the one from index.d.ts
in version 16.9.49.
Part A: yes, that's the way to do.
Part B: as you can see at line 658, error
is of type any
and the return type is a partial of the state
or null
.
Part C: at line 641, you will see that error is of type Error
and return type is void
.
Part D: at line 494, you can see that render should return a ReactNode
…