简体   繁体   English

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

[英]How can I make use of Error boundaries in functional React components?

I can make a class an error boundary in React by implementing componentDidCatch .我可以通过实现componentDidCatch 使一个类成为 React 中的错误边界

Is there a clean approach to making a functional component into an error boundary without converting it into a class?是否有一种干净的方法可以将功能组件变成错误边界而不将其转换为类?

Or is this a code smell?或者这是代码的味道?

As of v16.2.0, there's no way to turn a functional component into an error boundary.从 v16.2.0 开始,无法将功能组件转变为错误边界。

The React docs are clear about that , although you're free to reuse them as many times as you wish: React 文档对此很清楚,尽管您可以随意多次重用它们:

The componentDidCatch() method works like a JavaScript catch {} block, but for components. componentDidCatch()方法的工作方式类似于 JavaScript catch {}块,但用于组件。 Only class components can be error boundaries.只有类组件可以是错误边界。 In practice, most of the time you'll want to declare an error boundary component once and use it throughout your application.在实践中,大多数时候您希望声明一次错误边界组件并在整个应用程序中使用它。

Also bear in mind that try/catch blocks won't work on all cases .还要记住, try/catch并不适用于所有情况
If a component deep in the hierarchy tries to updates and fails, the try/catch block in one of the parents won't work -- because it isn't necessarily updating together with the child.如果层次结构深处的组件尝试更新并失败,则其中一个父级中的try/catch块将不起作用——因为它不一定与子级一起更新。

There is an implementation that can handle with non-existent functionalities for a functional component such as componentDidCatch and deriveStateFromError .有一个实现可以处理功能组件不存在的功能,例如componentDidCatchderiveStateFromError

According to the author, it is based on React.memo().据作者介绍,它基于 React.memo()。

The proposed solution is greatly inspired by the new React.memo() API.提议的解决方案受到新的 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>
  }
})

reference and API here参考和API 在这里

As mentioned already, the React team has not yet implemented a hook equivalent , and there are no published timelines for a hook implementation.如前所述,React 团队还没有实现等效的钩子,也没有发布钩子实现的时间表

A few third party packages on npm implement error boundary hooks. npm 上的一些第三方包实现了错误边界挂钩。 I published react-use-error-boundary , attempting to recreate an API similar to useErrorBoundary from Preact :我发布了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>;
});

Official React team not provided Error boundary support for functional component.官方 React 团队没有为功能组件提供错误边界支持。 We can achieve error boundary for functional component using npm package.我们可以使用 npm 包实现功能组件的错误边界。 https://www.npmjs.com/package/react-error-boundary https://www.npmjs.com/package/react-error-boundary

What I have done is create custom class component and wrapped my functional/class component inside it where ever its required.我所做的是创建自定义class component并将我的functional/class组件包装在它需要的地方。 This is how my custom class component looks like:这是我的自定义类组件的样子:

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}</>;
    }
  }
}

And used it like this my functional/class components:并像这样使用它我的functional/class组件:

<ErrorBoundary key={uniqueKey}>
   <FuncationalOrChildComponent {...props} />
</ErrorBoundary>

PS: As usual the key property is very important as it will make sure to re-render the ErrorBoundary component if you have dynamic child elements. PS:像往常一样, key 属性非常重要,因为如果您有动态子元素,它将确保重新渲染ErrorBoundary组件。

Official React team not yet provided Error boundary hook for functional component.官方 React 团队尚未为功能组件提供错误边界钩子。 But you can achieve error boundary for functional component using third party packages like.但是你可以使用第三方包来实现功能组件的错误边界。 https://www.npmjs.com/package/react-error-boundary But it still have some issues so i recommend not to use it https://www.npmjs.com/package/react-error-boundary但它仍然有一些问题所以我建议不要使用它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM