我可以通过实现 componentDidCatch来反应 使类成为错误边界。
componentDidCatch
有没有一种干净的方法可以使一个函数组件成为一个错误边界,而不需要将它转换成一个类?
还是代码的味道?
在 v16.2.0中,没有办法将函数组件转换为错误边界。
React 文档很清楚这一点,尽管你可以随心所欲地重用它们:
componentDidCatch()方法的工作方式类似于 JavaScriptcatch {}块,但是适用于组件
componentDidCatch()
catch {}
还要记住,try/catch阻止 不是所有案子都有效。 如果层次结构中的一个组件尝试更新但失败,那么其中一个父组件中的 try/catch块就不能工作——因为它不一定与子组件一起更新。
try/catch
有一个实现可以处理功能组件(如 componentDidCatch和 deriveStateFromError)不存在的功能。
deriveStateFromError
根据作者的说法,它是基于 React.note ()的。
提出的解决方案极大地受到了新的 React.note () 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> } })
参考资料及 API 给你
正式反应小组没有为功能部件提供错误边界支持。 利用 npm 软件包可以实现函数型构件的误差边界。 Https://www.npmjs.com/package/react-error-boundary
如前所述,React 团队有 尚未实现钩子等价物,而钩子实现有 没有公开的时间线。
Npm 上的一些第三方包实现了错误边界钩子。我发布了 反应-使用-错误-边界,试图重新创建一个类似于 来自 Preact 的边界的 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>; });
我所做的是创建自定义 class component,并在需要的地方将我的 functional/class组件包装在其中。下面是我的自定义类组件的外观:
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}</>; } } }
像这样使用我的 functional/class组件:
<ErrorBoundary key={uniqueKey}> <FuncationalOrChildComponent {...props} /> </ErrorBoundary>
PS: 和往常一样,键属性非常重要,因为如果您有动态子元素,它将确保重新呈现 ErrorBoundary组件。
ErrorBoundary