React最佳实践中的错误处理

Ken*_*iwa 24 reactjs

在React中渲染组件(具有许多子组件)并且由于某种原因抛出JS错误时,处理此问题的最佳方法是什么?当然,我可以捕获错误,但最终你想要呈现的东西可能无法,因为缺少需要的信息.您可以使用.isRequiredpropTypes 提前验证,但只有控制台失败时才会发出警告.

Tha*_*ara 27

React 16引入了一个名为"错误边界"的新概念来处理React组件内部发生的错误,而不会破坏整个应用程序.

错误边界是React组件,它们在其子组件树中的任何位置捕获JavaScript错误,记录这些错误,并显示回退UI而不是崩溃的组件树.

错误使用新的生命周期方法可以实现边界组件componentDidCatch(error, info).与其他生命周期方法不同,只有在渲染期间,生命周期方法或组件的任何子级(包括所有子级)组件的构造函数中发生任何错误时,才会调用此方法.

在代码中,Error Boundary组件将如下所示.

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

  componentDidCatch(error, info) {
    // Display fallback UI
    this.setState({ hasError: true });
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Error occurred!</h1>;
    }
    return this.props.children;
  }
}
Run Code Online (Sandbox Code Playgroud)

我们可以将此Error Boundary组件用作代码中的普通组件.

<ErrorBoundary>
  <MyComponent />
</ErrorBoundary>
Run Code Online (Sandbox Code Playgroud)

现在,如果MyComponent在渲染,生命周期方法或构造过程中抛出任何JavaScript错误,componentDidCatch则Error Boundary组件将触发并更改状态以显示Error occurred!消息而不是损坏的MyComponent.

这个新功能带来了在迁移到React 16之前您想知道的另一个重要含义.以前,如果发生错误,它会留下损坏的UI,即使它通常不能按预期工作,直到您重新加载页面.但是,在React 16中,如果任何错误边界没有处理错误,则会导致整个应用程序的卸载.

因此,适当地为您的应用添加错误边界将为您的用户提供更好的体验.因此,即使某些UI区域崩溃,用户也可以与您的应用程序的一部分进行交互.

有关更多信息,请参阅有关错误边界的React官方文档此官方博客文章.它们几乎涵盖了您需要了解的有关此新功能的所有内容.


Joh*_*ell 5

通常你不应该有一些会导致js错误的东西.如果它等待来自服务器的数据然后不渲染它.除此之外,你会有某种形式的通知/消息显示它尚未加载.

因此,例如,如果您有一个将要渲染东西的组件,您可以有条件地渲染组件.

又名

render(){
  let {serverData} = this.props;
  return (
    <div className="something">
      {Boolean(serverData) && serverData.length > 0 
        ? <MyComponent data={serverData} />
        : <LoadingComponent />
      }
    </div>
  )
}
Run Code Online (Sandbox Code Playgroud)

现在,这只是描述我所谈论内容的一个基本例子.Javascript异常将破坏您的单页应用程序,您不应该有任何.如果无效的内容重定向到404页面.如果组件需要数据,则等待数据呈现它.

另一个重要的事情是,如果你试图访问this.props.myData.obj.something.somethingelse那些对象路径不会永远存在的机会.你需要确保每个都没有未定义或为null.我使用的lodash具有很棒的功能

_.get(this.props, 'myData.obj.something.somethingelse')` 
Run Code Online (Sandbox Code Playgroud)

如果任何这些键不存在或未定义/不是对象,则返回undefined

我想故事的寓意是你应该主动在你的代码中捕获可能破坏的东西,从不假设变量类型以及它的数据将在那里:)

  • 所以答案是"发送无错误代码"?我是一个新的React转换器,我对所有的胜利感到激动......但我也一直在运送软件二十五年,这种态度听起来很幼稚.当然,避免错误是最好的做法,但问题是关于*处理*错误 - 不可否认,这是一种较小的艺术形式,但仍然是必要的.您无法控制100%的代码.你不可能预见到可能出错的一切.OP和我想知道React处理**发生的错误的惯用方法是什么. (34认同)