在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
这是React16的内容,并不是最新的技术,但是用很少被讨论,直到通过文档发现其实也是很有用的一部分内容,还是总结一下~ React中的未捕获的 JS 错误会导致整个应用的崩溃,和整个组件树的卸载。从 React16 开始就是这样。但是同时React也引入了一个新的概念——错误边界。 定义,是什么错误边界仍然是一种组件,可以捕获(打印或者其他方式)处理该组件的子组件树任何位置的 JavaScript 错误,并根据需要渲染出备用UI. 工作方式类似于try-catch,但是错误边界只用于 React 组件。 只有class组件能够成为错误边界组件。错误边界仅可以捕获子组件的错误,无法捕获自身的错误。 错误边界会在渲染期间,生命周期和整个组件树的构造函数中捕获错误。如果没有错误边界处理,渲染的还是崩溃的子组件树,这显然不是我们想要的。 通过一个例子来逐步演示要怎么用错误边界: export default class ErrorTest extends Component { constructor(props) { super(props); } render() { return ( <div> <BugCounter></BugCounter> <span>my name is dan</span> </div> ); } } // Bug 报错组件 class BugCounter extends Component { constructor(props) { super(props); this.state = { counter: 0, }; } click = () => { this.setState(({ counter }) => ({ counter: counter + 1 })); }; render() { if (this.state.counter === 5) { throw new Error("crashed!"); } return ( <div> <h3 onClick={this.click}>{this.state.counter}</h3> </div> ); } } 上面代码的渲染结果(忽略样式): 点击数字 该 生产模式下,会直接白屏,并在控制台报错: getDerivedStateFromError & componentDidCatch 需要一个错误边界来处理这种崩溃。如何定义一个错误边界? 定义一个组件,并实现 关于这两个生命周期函数,可以通过链接查看,总结如下: componentDidCatch(error, info)
static getDerivedStateFromError(error) 在子组件抛出错误后调用,会将抛出的错误作为参数。需要返回一个值,以更新state。该函数在渲染阶段调用,不允许出现副作用。如果在捕获错误后需要执行副作用操作,应该在 制作错误边界组件可以使用组合的方式,在要使用的组件上面添加一个错误边界组件包裹一层。该组件需要这些效果:
那么就可以像这样: 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; } } 捕获到错误之后的副作用是自定义的,上传服务器,或者用 componentDidCatch(error, errorInfo) { // Catch errors in any components below and re-render with error message this.setState({ error: error, errorInfo: errorInfo }) } 捕获处理加上所有代码,将有问题的组件用错误边界的组件包裹起来,看看结果: import { Component } from "react"; export default class ErrorTest extends Component { render() { return ( <div> <ErrorBoundary> <BugCounter></BugCounter> </ErrorBoundary> <span>my name is dan</span> </div> ); } } // Bug 报错组件 class BugCounter extends Component { constructor(props) { super(props); this.state = { counter: 0, }; } click = () => { this.setState(({ counter }) => ({ counter: counter + 1 })); }; render() { if (this.state.counter === 5) { throw new Error("crashed!"); } return ( <div> <h3 onClick={this.click}>{this.state.counter}</h3> </div> ); } } // 错误边界处理组件 class ErrorBoundary extends Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { // 更新 state 使下一次渲染能够显示降级后的 UI return { hasError: true }; } render() { if (this.state.hasError) { // 你可以自定义降级后的 UI 并渲染 return <h1>Something went wrong.</h1>; } return this.props.children; } } 抛出异常在开发模式下依然是报错的,但是在使用 可以看到,虽然因为 作用范围错误边界用于处理子组件生命周期和渲染函数上的错误,对于事件处理器,不会在渲染期间触发,对于事件处理器抛出的异常应该用 错误边界无法捕获这些场景中的错误:
关于错误边界,一个 https://codepen.io/gaearon/pen/wqvxGa?editors=0010 参考:https://zh-hans.reactjs.org/docs/error-boundaries.html https://zh-hans.reactjs.org/docs/react-component.html https://codepen.io/gaearon/pen/wqvxGa?editors=0010 到此这篇关于React 错误边界组件的处理的文章就介绍到这了,更多相关React 错误边界内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论