• React.js |错误边界


    前言:做笔记,参考:react文档,文章涉及的示例:https://sanhuamao1.coding.net/public/note/myapp/git/files/13Error-Boundaries

    错误边界

    错误边界是一种 React 组件,可以捕获并打印发生在其子组件树任何位置的 JavaScript 错误,并且渲染出备用 UI。错误边界在渲染期间、生命周期和整个组件树的构造函数中捕获错误。

    它无法在以下场景捕获错误:

    • 事件处理(了解更多)
    • 异步代码(例如 setTimeout 或 requestAnimationFrame 回调函数)
    • 服务端渲染
    • 它自身抛出来的错误(并非它的子组件)

    使用方式

    这是两种生命周期方法。只要class组件用了任意一种,那它就变成一个错误边界组件


    方式一:componentDidCatch()

    class ErrorBoundary extends React.Component {
        constructor(props) {
          super(props);
          this.state = { hasError: false };
        }
        componentDidCatch(error, errorInfo) {
          this.setState({
              error:error,
              errorInfo:errorInfo
          })
        }
        render() {
          if (this.state.errorInfo) {
            return <div>
                {this.state.error&&this.state.error.toString()}<br/> {this.state.errorInfo.componentStack}
            </div>
            
          }
          //正常则返回子元素,即该组件包裹的元素
          return this.props.children; 
        }
     }
    

    一个测试组件,如果输入的是非字母就会报错:

    class Example extends React.Component{
        constructor(props){
            super(props)
            this.state={value:""}
            this.handleChange=(e)=>{
                this.setState({value:e.target.value})
            }
        }
        render(){
            const value=this.state.value
            if(/^[a-zA-Z]+$/.test(value)||value===""){
                return  <input type="text" onChange={this.handleChange} placeholder="只能填字母"/>
            }
            throw new Error('出错了!');
        }
    }
    

    App.js

    <ErrorBoundary>
       <Example />
    </ErrorBoundary>
    

    方式二:static getDerivedStateFromError()

    class ErrorBoundary extends React.Component {
        constructor(props) {
          super(props);
          this.state = { hasError: false };
        }
        static getDerivedStateFromError(error) {
          return { hasError: true };
        }
        
        render() {
          if (this.state.hasError) {
            //显示降级UI
            return <div>出错了bro!</div>
          }
          return this.props.children; 
        }
     }
    

    image.png


    你也可以同时使用两种。

    看样子componentDidCatch()好像没什么用,因为一般情况下浏览器会告诉你只能在控制台看错误日志,并且在没有使用该错误边界组件的情况下,控制台也会打印出同样的错误信息。相比之下,能渲染出备用组件的static getDerivedStateFromError()的实用性高一点。其实,无论使用哪一种,它都起到了创建错误边界组件的作用。

    错误边界组件的工作方式类似于 JavaScript 的 catch {},不同之处在于它只针对 React 组件。且只有 class 组件才可以成为错误边界组件。注意,它无法捕获其自身的错误。

    如果没有使用错误边界会怎样?

    自 React 16 起,任何未被错误边界捕获的错误将会导致整个 React 组件树被卸载。

    经验告诉我们,完全移除比保留错误UI更好。例如,在类似 Messenger 的产品中,把异常的 UI 展示给用户可能会导致用户将信息错发给别人。

    增加错误边界能够让你在应用发生异常时提供更好的用户体验。例如,Facebook Messenger 将侧边栏、信息面板、聊天记录以及信息输入框包装在单独的错误边界中。如果其中的某些 UI 组件崩溃,其余部分仍然能够交互。

    try/catch的缺陷

    try / catch 很棒但它仅能用于命令式代码:

    try {
      showButton();
    } catch (error) {
      // ...
    }
    

    然而,React 组件是声明式,并且具体指出 什么 需要被渲染:

    <Button />
    

    为什么无法捕获事件处理器的内部错误?

    React 不需要错误边界来捕获事件处理器中的错误。与 render 方法和生命周期方法不同,事件处理器不会在渲染期间触发。因此,如果它们抛出异常,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 <h1>捕获到一个错误</h1>
        }
        return <button onClick={this.handleClick}>点击</button>
      }
    }
    
  • 相关阅读:
    数据挖掘入门系列教程(九)之基于sklearn的SVM使用
    问题_001_Vivian
    TypeScript学习笔记(五)
    TypeScript学习笔记(四)
    TypeScript学习笔记(三)
    TypeScript学习笔记(二)
    TypeScript学习笔记(一)
    使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(十)-- 发布(Windows)
    使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(九)-- 单元测试
    使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(八)-- 多环境开发
  • 原文地址:https://www.cnblogs.com/sanhuamao/p/13736804.html
Copyright © 2020-2023  润新知