如何处理React中的错误

369 阅读2分钟

使用错误边界处理React中的错误的最佳实践

当使用一个组件时,当这个组件代码内发生任何错误时,React将卸载整个React组件树,渲染任何东西。这就是React处理崩溃的方式。

你不希望错误出现在你的用户面前。React决定显示一个空白页面。

然而,这只是默认情况。让一个空白页显示出来只是比向用户显示隐秘的信息好一点,但你应该有更好的方法。

如果你在开发模式下,任何错误都会触发一个详细的堆栈跟踪,打印到浏览器DevTools控制台。然而,在生产中就不一样了,你并不希望把错误打印出来给你的用户。

在生产中,你应该拦截错误,并向使用该应用程序的人显示某种有用的信息。

这就是错误边界发挥作用的地方。

有了错误边界,你就可以隔离应用程序的某些部分并在本地处理错误。

错误边界是一个React组件,它实现了componentDidCatch() 生命周期事件,并封装了其他组件。

class ErrorHandler extends React.Component {
  constructor(props) {
    super(props)
    this.state = { errorOccurred: false }
  }

  componentDidCatch(error, info) {
    this.setState({ errorOccurred: true })
    logErrorToMyService(error, info)
  }

  render() {
    return this.state.errorOccurred ? <h1>Something went wrong!</h1> : this.props.children
  }
}

并在组件的JSX中,你这样使用它。

<ErrorHandler>
  <SomeOtherComponent />
</ErrorHandler>

当错误发生在SomeOtherComponent 或其他子组件内,以及它们所持有的整个组件子树中时,ErrorHandler 将会拦截它,你可以优雅地处理错误。

在上述案例中,我们受到React官方文档的启发,有一个errorOccurred 状态属性,当设置为真时,会使界面呈现错误处理的UI,否则会呈现正常的应用程序UI树。

componentDidCatch() ,它接收2个描述错误的参数,我们还调用logErrorToMyService() ,这只是一个函数的存根,该函数使用Sentry、Roller、Airbrake或其他服务,可以以一种漂亮的方式记录错误,让你看到,所以你不必依靠用户告诉你有一个错误来注意一个问题。