如何在Typescript中正确键入React ErrorBoundary类组件?

问题描述

这是我目前在如何在Typescript中正确键入React ErrorBoundary类组件的尝试:

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;

这个问题是关于这个ErrorBoundary类组件的类型的。我将其分成几部分以使其变得更容易。


部分A:道具和状态的类型

我在做什么对吗?

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> {}

部分B:getDerivedStateFromError(错误

我应该为error参数选择哪种类型?返回类型应该是State类型,对吧?

static getDerivedStateFromError(error): State {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

PART C:componentDidCatch(错误,errorInfo:React.React.ErrorInfo)

我应该为error参数选择哪种类型?对于errorInfo,React确实有一个ErrorInfo类型,似乎是正确的。是吗?返回类型应该为void,对吗?

componentDidCatch(error,errorInfo: React.ErrorInfo): void {
    console.log("error: " + error);
    console.log("errorInfo: " + JSON.stringify(errorInfo));
    console.log("componentStack: " + errorInfo.componentStack);
}

PART D:render()方法

返回类型应该为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;
  }

解决方法

您将从index.d.ts的文件@types/react中获得所有答案。如果您使用的是类似VSCode的IDE,则可以按住Ctrl键并单击某个类型以直接转到其定义。

这是您问题的精确答案,但在此之前,让我建议您最好使用react hooks而不是课堂。


由OP进行编辑:我从不使用类组件,始终喜欢使用函数和钩子,而是从React docs的错误边界上来的:

错误边界的工作原理类似于JavaScript catch {}块,但适用于组件。 仅类组件可以是错误边界。


我给出的行是16.9.49版中的index.d.ts中的行。

A部分:是的,就是这样。

B部分:如第658行所示,error类型为any,返回类型为state或{ {1}}。

C部分:在第641行,您将看到错误类型为null,返回类型为Error

D部分:在第494行,您可以看到渲染器应返回void