如何在功能性React组件中使用错误边界?

Dan*_*umb 13 error-handling reactjs

通过实现,我可以使类成为 React中的错误边界componentDidCatch

是否有一种干净的方法可以将功能组件转换为错误边界而不将其转换为类?

还是这是代码气味?

Tat*_*ton 23

如前所述,React 团队尚未实现等效的钩子,并且没有发布钩子实现的时间表。

npm 上的一些第三方包实现了错误边界挂钩。我发布了react-use-error-boundary ,尝试从Preact重新创建一个类似于useErrorBoundary的API :

import { withErrorBoundary, useErrorBoundary } from "react-use-error-boundary";

const App = withErrorBoundary(({ children }) => {
  const [error, resetError] = useErrorBoundary(
    // You can optionally log the error to an error reporting service
    (error, errorInfo) => logErrorToMyService(error, errorInfo)
  );

  if (error) {
    return (
      <div>
        <p>{error.message}</p>
        <button onClick={resetError}>Try again</button>
      </div>
    );
  }

  return <div>{children}</div>;
});
Run Code Online (Sandbox Code Playgroud)


gus*_*nke 16

从v16.2.0开始,无法将功能组件转换为错误边界。

React文档对此很清楚,尽管您可以随意重用它们:

componentDidCatch()方法的工作方式类似于JavaScript catch {}块,但适用于组件。只有类组件才能成为错误边界。实际上,大多数情况下,您需要一次声明一个错误边界组件,并在整个应用程序中使用它。

还要记住,try/catch方块不适用于所有情况
如果层次结构中的某个组件尝试更新并失败,则try/catch其中一个父级中的块将不起作用-因为它不一定与子级一起更新。

  • 那么您推荐的替代方案是什么? (3认同)

Dip*_*pak 16

我所做的是创建自定义class component并将我的functional/class组件包装在其中需要的地方。这就是我的自定义类组件的样子:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = {error: ""};
  }

  componentDidCatch(error) {
    this.setState({error: `${error.name}: ${error.message}`});
  }

  render() {
    const {error} = this.state;
    if (error) {
      return (
        <div>{error}</div>
      );
    } else {
      return <>{this.props.children}</>;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用我的functional/class组件:

<ErrorBoundary key={uniqueKey}>
   <FuncationalOrChildComponent {...props} />
</ErrorBoundary>
Run Code Online (Sandbox Code Playgroud)

ErrorBoundaryPS:像往常一样, key 属性非常重要,因为如果您有动态子元素,它将确保重新渲染组件。


Lui*_*bro 15

有一种实现可以处理功能组件不存在的功能,例如componentDidCatchderiveStateFromError

据作者介绍,它基于 React.memo()。

提议的解决方案深受新 React.memo() API 的启发。

import Catch from "./functional-error-boundary"

type Props = {
  children: React.ReactNode
}

const MyErrorBoundary = Catch(function MyErrorBoundary(props: Props, error?: Error) {
  if (error) {
    return (
      <div className="error-screen">
        <h2>An error has occured</h2>
        <h4>{error.message}</h4>
      </div>
    )
  } else {
    return <React.Fragment>{props.children}</React.Fragment>
  }
})
Run Code Online (Sandbox Code Playgroud)

参考和API在这里


Suj*_*jit 12

React 官方团队未提供对功能组件的错误边界支持。我们可以使用 npm 包实现功能组件的错误边界。 https://www.npmjs.com/package/react-error-boundary