React用错误边界来捕获和处理异常错误!

AI炼丹童子
• 阅读 184
一、解决什么问题?

UI 中 JavaScript 错误不应该导致整个应用崩溃,错误边界就是解决方案(React 16 增加的功能)。


二、有哪些特性?
1、定义
  • 可捕获子组件 JavaScript 错误,打印错误并展示备用UI的clas组件。
2、无法捕获的错误:
  • 事件处理
  • 异步代码(例如 setTimeoutrequestAnimationFrame 回调函数)
  • 服务端渲染
  • 它自身抛出来的错误(并非它的子组件)
3、怎么写?

错误边界是包含下面任意一个或两个方法 的class组件:

  • static getDerivedStateFromError() :渲染备用 UI
  • componentDidCatch() :打印错误信息
//  错误边界  实例
class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props);
        this.state = { hasError: false };
    }

    static getDerivedStateFromError(error) {
        // 更新 state 使下一次渲染能够显示降级后的 UI
        return { hasError: true };
    }

    componentDidCatch(error, errorInfo) {
        // 你同样可以将错误日志上报给服务器
        logErrorToMyService(error, errorInfo);
    }

    render() {
        if (this.state.hasError) {
            // 你可以自定义降级后的 UI 并渲染
            return <h1>Something went wrong.</h1>;
        }

        return this.props.children;
    }
}
// 使用 错误边界
<ErrorBoundary>
    <MyWidget />
</ErrorBoundary>

4、js代码还是用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>Caught an error.</h1>
        }
        return <button onClick={this.handleClick}>Click Me</button>
    }
}

三、实例展示

一个使用 错误边界 的示例,新建并复制下面代码到index.html文件,浏览器打开index.html即可看到效果。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    <!-- 第一步:加载开发版本的React -->
    <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

    <!-- 部署时,请用下面链接替代上面 -->
    <!-- <script src="https://unpkg.com/react@16/umd/react.production.min.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js" crossorigin></script> -->

    <!-- 第二步:加载开发版本的babel -->
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

</head>

<body>
    <div id="root"></div>
    <script type="text/babel">
        class ErrorBoundary extends React.Component {
            constructor(props) {
                super(props);
                this.state = { error: null, errorInfo: null };
            }

            componentDidCatch(error, errorInfo) {
                // Catch errors in any components below and re-render with error message
                this.setState({
                    error: error,
                    errorInfo: errorInfo
                })
                // You can also log error messages to an error reporting service here
            }

            render() {
                if (this.state.errorInfo) {
                    // Error path
                    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>
                    );
                }
                // Normally, just render children
                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 === 5) {
                    // Simulate a JS error
                    throw new Error('I crashed!');
                }
                return <h1 onClick={this.handleClick}>{this.state.counter}</h1>;
            }
        }

        function Err() {
            return (
                <div>
                    <p>
                        <b>
                            This is an example of error boundaries in React 16.
                            <br /><br />
                            Click on the numbers to increase the counters.
                            <br />
                            The counter is programmed to throw when it reaches 5. This simulates a JavaScript error in a component.
                        </b>
                    </p>
                    <hr />
                    <ErrorBoundary>
                        <p>These two counters are inside the same error boundary. If one crashes, the error boundary will replace both of them.</p>
                        <BuggyCounter />
                        <BuggyCounter />
                    </ErrorBoundary>
                    <hr />
                    <p>These two counters are each inside of their own error boundary. So if one crashes, the other is not affected.</p>
                    <ErrorBoundary><BuggyCounter /></ErrorBoundary>
                    <ErrorBoundary><BuggyCounter /></ErrorBoundary>
                </div>
            );
        }

        ReactDOM.render(
            <Err />,
            document.getElementById('root')
        );

    </script>
</body>
</html>

四、参考文档:
点赞
收藏
评论区
推荐文章
Karen110 Karen110
4年前
一篇文章带你了解JavaScript错误处理
大家好,我是前端进阶者。执行JavaScript代码时,可能会发生意想不到的错误。错误可以是程序员编写的编码错误,由于输入错误引起的错误以及其他不可预见的事情。因此,为了处理错误,JavaScript提供了4个关键字。一、JavaScripttry...catch语句try语句允许定义一个代码块,该代码块在执行时将进行错误测试,catch如果try块中
Wesley13 Wesley13
4年前
java异常处理
_1.异常的分类_Error:称为错误,有java虚拟机生成并抛出,包括动态链接失败、虚拟机错误等,程序对其不做处理。Exception:所以异常类的父类,其子类对应了各种各样可能出现的异常,一般需要用户显示的声明或捕获。RuntimeException:一类特殊的异常,如被0除,数组下标超范围等,其产生比较频繁,处理比较麻烦,如果显示
Wesley13 Wesley13
4年前
Java中的异常
异常的概述异常就是不正常的意思,Java语言中主要指程序在运行阶段产生的错误Throwable(可抛出、可扔出的)Java.lang.Throwable类是Java程序所有错误或异常的超类主要有两个子类:  Error:主要描述比较严重的错误,无法通过编程来解决的重大的错误  Exception:主要描述比较轻量
Stella981 Stella981
4年前
JavaScript Errors 指南
在README文件中包含了这么多年我对JavaScripterrors的学习和理解,包括把错误报告给服务器、在众多bug中根据错误信息追溯产生错误的原因,这些都使得处理JavaScript错误变得困难。浏览器厂商在处理JavaScript错误方面也有所改进,但是保证应用程序能够稳健地处理JavaScript错误仍然有提升的空间。Introdu
Stella981 Stella981
4年前
JavaScript常见的10个错误
10种最常见的Javascript错误以下是JavaScript错误Top10:为了便于阅读,我们将每个错误描述都缩短了。接下来,让我们深入到每一个错误,来确定什么会导致它,以及如何避免创建它。1\.UncaughtTypeError:Cannotreadprope
Stella981 Stella981
4年前
ClassNotFoundException和NoClassDefFoundError的区别
!(https://static.oschina.net/uploads/space/2018/0316/102545_BlhC_999023.png)1.NoClassDefFoundError是一个错误(Error),而ClassNOtFoundException是一个异常,在Java中错误和异常是有区别的,我们可以从异常中恢复程序但却不应该
小万哥 小万哥
2年前
C++异常和错误处理机制:如何使您的程序更加稳定和可靠
在C编程中,异常处理和错误处理机制是非常重要的。它们可以帮助程序员有效地处理运行时错误和异常情况。本文将介绍C中的异常处理和错误处理机制。什么是异常处理?异常处理是指在程序执行过程中发生异常或错误时,程序能够捕获并处理这些异常或错误的机制。例如,当
小万哥 小万哥
2年前
Python 异常处理:try、except、else 和 finally 的使用指南
异常处理当发生错误(或我们称之为异常)时,Python通常会停止执行并生成错误消息。try块用于测试一段代码是否存在错误。except块用于处理错误。else块用于在没有错误时执行代码。finally块用于无论try和except块的结果如何都要执行的代码
JavaScript 常见错误与异常处理
一、为什么要了解常见JS错误1、调试和故障排除:了解常见的JavaScript错误可以帮助你更好地调试和故障排除代码。当你遇到错误时,能够快速识别错误类型并找到解决方法,可以节省大量的时间和精力。2、代码质量和稳定性:通过了解常见的JavaScript错误
小万哥 小万哥
1年前
C++ 异常处理机制详解:轻松掌握异常处理技巧
C异常处理C异常处理机制允许程序在运行时处理错误或意外情况。它提供了捕获和处理错误的一种结构化方式,使程序更加健壮和可靠。异常处理的基本概念:异常:程序在运行时发生的错误或意外情况。抛出异常:使用throw关键字将异常传递给调用堆栈。捕获异常:使用
程序员小五 程序员小五
1年前
融云IM干货丨IM服务,在开发过程中,如何自动化处理SDK日志中的错误码
在开发过程中,自动化处理SDK日志中的错误码可以通过以下几个步骤实现:错误码解析:利用SDK提供的错误码对照表,将错误码映射到具体的错误信息和解决方案。例如,阿里云日志服务提供了详细的错误码对照表及对应的解决方法。异常捕获与处理:SDK通常会抛出异常来处理
AI炼丹童子
AI炼丹童子
Lv1
四张机,鸳鸯织就欲双飞,可怜未老头先白;春波碧草,晓寒深处,相对浴红衣。
文章
6
粉丝
0
获赞
0