个性化阅读
专注于IT技术分析

React使用错误边界处理错误 – ReactJS实战教程

上一章ReactJS实战教程请查看:React Portal(插槽)用法全解

在过去,如果我们在组件中得到任何JavaScript错误,它会破坏React的内部状态,在接下来的渲染React状态将会比较难处理。React组件中没有处理这些错误的方法,也没有提供任何从中恢复的方法。但是,React 16引入了一个新概念,通过使用错误边界来处理错误。现在,如果在部分UI中发现任何JavaScript错误,它不会破坏整个应用程序。

错误边界是React组件,它捕捉应用程序中任何地方的JavaScript错误,记录这些错误,并显示备用UI。它不会破坏整个app组件树,只会在组件发生错误时呈现回退UI。错误边界捕获组件生命周期方法中呈现期间的错误,以及它们下面整个树的构造函数。

注意:

有时,在React应用程序中捕获错误边界是不可能的。这些都是:

  • 事件处理程序
  • 异步代码(例如setTimeout或requestAnimationFrame回调)
  • 服务器端渲染
  • 错误将在错误边界中抛出,而不是在其子边界中抛出。

对于简单的React应用程序,我们可以一次性声明一个错误边界,并将其用于整个应用程序。对于具有多个组件的复杂应用程序,我们可以声明多个错误边界来恢复整个应用程序的每个部分。

我们还可以向类似Rollbar的错误监视服务报告错误,此监视服务提供了跟踪有多少用户受到错误影响、查找错误原因并改进用户体验的能力。

类内的错误边界

如果类组件定义了一个新的生命周期方法(静态getDerivedStateFromError()或componentDidCatch(error, info)),它就可能成为一个错误边界。我们可以使用静态的getDerivedStateFromError()在抛出错误时呈现回退UI,还可以使用componentDidCatch()来记录错误信息。

错误边界无法捕获其内部的错误。如果错误边界未能呈现错误消息,则错误将转到其上最近的错误边界。它类似于JavaScript中的catch{}块。

如何实现错误边界

步骤1: 创建一个扩展React组件并在其类中传递props。

步骤2: 现在,添加componentDidCatch()方法,它允许你捕获树中它们下面的组件中的错误。

步骤3: 接下来添加render()方法,该方法负责如何呈现组件。例如,它将显示“Something is wrong”这样的错误消息。

例子

class ErrorBoundary extends React.Component {  
  constructor(props) {  
    super(props);  
    this.state = { hasError: false };  
  }  
  static getDerivedStateFromError(error) {  
    // 它将更新状态,以便在下一个呈现中显示回退UI  
    return { hasError: true };  
  }  
  componentDidCatch(error, info) {  
    // 它将捕获错误的任何组件如下。我们还可以将错误记录到错误报告服务中
    logErrorToMyService(error, info);  
  }  
  render() {  
    if (this.state.hasError) {  
        return (  
        <div>Something is wrong.</div>;  
    );  
    }  
    return this.props.children;   
  }  
}  

步骤4: 现在,我们可以将它作为常规组件使用,在HTML中添加你希望包含在错误边界中的新组件。在本例中,我们在MyWidgetCounter组件周围添加了一个错误边界。

<ErrorBoundary>  
       <MyWidgetCounter/>  
</ErrorBoundary>  

在哪里放置错误边界?

错误边界完全取决于你。你可以在应用程序组件的顶层使用错误边界,或者将其包装在各个组件上,以保护它们不破坏应用程序的其他部分。

让我们来看一个例子。

import React from 'react';  
import './App.css'  
  
class ErrorBoundary extends React.Component {  
  constructor(props) {  
    super(props);  
    this.state = { error: false, errorInfo: null };  
  }  
    
  componentDidCatch(error, errorInfo) {  
    // 捕获下面任何组件中的错误,并使用错误消息重新渲染
    this.setState({  
      error: error,  
      errorInfo: errorInfo  
    })  
  }  
    
  render() {  
    if (this.state.errorInfo) {  
      return (  
        <div>  
          <h2>Something went wrong.</h2>  
          <details style={{ whiteSpace: 'pre-wrap' }}>  
            {this.state.error && this.state.error.toString()}  
            <br />  
            {this.state.errorInfo.componentStack}  
          </details>  
        </div>  
      );  
    }  
    return this.props.children;  
  }    
}  
  
class BuggyCounter extends React.Component {  
  constructor(props) {  
    super(props);  
    this.state = { counter: 0 };  
    this.handleClick = this.handleClick.bind(this);  
  }  
    
  handleClick() {  
    this.setState(({counter}) => ({  
      counter: counter + 1  
    }));  
  }  
    
  render() {  
    if (this.state.counter === 3) {  
      throw new Error('I crashed!');  
    }  
    return <h1 onClick={this.handleClick}>{this.state.counter}</h1>;  
  }  
}  
  
function App() {  
  return (  
    <div>  
      <p><b>错误边界的例子</b></p>  
      <hr />  
      <ErrorBoundary>  
        <p>这两个计数器位于相同的错误边界内</p>  
          <BuggyCounter />  
          <BuggyCounter />  
      </ErrorBoundary>  
      <hr />  
      <p>这两个计数器位于各自的错误边界内</p>  
        <ErrorBoundary><BuggyCounter /></ErrorBoundary>  
        <ErrorBoundary><BuggyCounter /></ErrorBoundary>  
    </div>  
  );  
}  
export default App  

在上面的代码片段中,当我们单击数字时,它会增加计数器。当计数器达到3时,程序会抛出错误,它模拟组件中的JavaScript错误。在这里,我们以两种方式使用误差边界,如下所示。

首先,这两个计数器位于相同的错误边界内,如果有人崩溃,错误边界将同时替换他们。

<ErrorBoundary>  
          <BuggyCounter />  
          <BuggyCounter />  
</ErrorBoundary>  

其次,这两个计数器位于各自的错误边界内。因此,如果有人崩溃,另一个就不会受到影响。

<ErrorBoundary><BuggyCounter /></ErrorBoundary>  
<ErrorBoundary><BuggyCounter /></ErrorBoundary>  

未捕获错误的新行为

这是与误差边界相关的一个重要含义。如果错误没有被任何错误边界捕获,将导致整个React应用程序的卸载。

事件处理程序中的错误边界

错误边界不允许在事件处理程序中捕获错误。React不需要任何错误边界来从事件处理程序中的错误中恢复。如果需要在事件处理程序中捕获错误,可以使用JavaScript try-catch语句。

在下面的示例中,你可以看到事件处理程序将如何处理错误。

class MyComponent extends React.Component {  
  constructor(props) {  
    super(props);  
    this.state = { error: null };  
    this.handleClick = this.handleClick.bind(this);  
  }  
  
  handleClick() {  
    try {  
      // 做一些会抛出错误的操作
    } catch (error) {  
      this.setState({ error });  
    }  
  }  
  
  render() {  
    if (this.state.error) {  
      return   
          <h2>它捕获了一个错误.</h2>  
    }  
    return <div onClick={this.handleClick}>点击</div>  
  }  
}  
赞(0)
未经允许不得转载:srcmini » React使用错误边界处理错误 – ReactJS实战教程

评论 抢沙发

评论前必须登录!