React 中的 ErrorBoundary

在 React 中,如果不做任何控制,当组件出现异常时,React 渲染就会停止,页面出现白屏,这种体验很不好。例如当用户输入某些非法数据,而前端都没有进行校验,页面出现白屏。这种情况下,最好的方式是只针对出错的组件进行处理,将出错的组件进行替换,替换成错误提示组件,并显示错误信息,可以指导用户的下一步操作。React 通过 ErrorBoundary 组件进行错误处理,当组件出现错误时,组件停止当前渲染并通过 Fiber 向上查找,如果找到 ErrorBoundary,就显示 Fallback 组件,否则出现白屏。

看一个简单的例子,主要看 Error 组件,当抛出异常时,会显示白屏。

复制代码
### App 组件
export default function App() {

  const AList = lazy(()=>import('./List.js'))
  const r = useRef(null)  
  const [show, setShow] = useState(false);
  
  return (
    <>
  
    <TODO/>
    <ErrorComponent/>
    </>
  );
}
### Error 组件
import React from 'react';

export function ErrorComponent(){
  
    // throw new Error('出错了!!');
    return <div style={{"text-align":"center", "font-size":"50px","color":"red"}}>错误</div>;
  
}

异常被注释掉时,组件正常显示。

打开注释,页面崩溃。

getDerivedStateFromError

在 React 中,如果想捕获子组件的异常需要定义 getDerivedStateFromError,当子组件出现异常时 React 会调用这个方法。ErrorBoundary 需要是一个类组件,在组件中定义 getDerivedStateFromError 方法。以下代码实现了 ErrorBoundary 组件,重点看 getDerivedStateFromError 方法。

复制代码
import React, { Component } from 'react';

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

  static getDerivedStateFromError(error) {
    // Update state so the next render shows the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    console.log('Logging error:', error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h1>组件出现异常</h1>;
    }

    return this.props.children; 
  }
}

export default ErrorBoundary;

将 ErrorComponent 设置为 Boundary 的子组件,组件被替换。

复制代码
    <ErrorBoundary>
      <ErrorComponent/>
    </ErrorBoundary>

React 如何实现

跟踪一下 React 代码,看 React 如何实现 getDerivedStateFromError,在组件发生异常时通过 try/catch 捕获并进入 handleError 方法

进入 handleError 并调用 throwException 方法

在 throwException 中判断是否存在 getDerivedStateFromError 方法,如果存在继续处理,进入createClassErrorUpdate

创建 update 并返回,update.payload 方法会调用 getDerivedStateFromError

将 update 加入 WIP 中的 updateQueue

从throwException 返回,进入 completeUnitOfWork,并返回 returnFiber (ErrorBoundary)。

最后最近进入finishClassComponent 渲染组件

总结

React 框架中通过 getDerivedStateFromError 方法进行异常处理,项目开发可以自定义一个类组件并实现该方法进行组件异常处理。

相关推荐
郑州光合科技余经理9 分钟前
国际版外卖系统:税率字段怎么和订单主流程解耦
android·java·开发语言·前端·后端·php·ai编程
梦想平凡38 分钟前
百游棋牌源代码开发搭建教程(十):隔离部署、备份恢复与双端验收
java·前端·javascript·数据库·源代码管理
yume_sibai2 小时前
06-Rust Web 开发实战(Axum 框架 + 数据库 + JWT 认证 + 中间件 + 部署)
前端·数据库·rust
计算机魔术师3 小时前
特朗普上台打给黄仁勋:AI末日论是骗局,我们绝不让它发生
前端
troy1283 小时前
Python 基础语法(八):Web 后端开发、数据分析与可视化、网络爬虫、人工智能 / 大模型应用
前端·python·数据分析
计算机魔术师3 小时前
CEO说要慢下来,黑客说别做梦了——同一篇论文,两种命运
前端
kyriewen4 小时前
我花3天抓了一个幽灵bug,凶手藏在第4层
前端·javascript·程序员
IT_陈寒5 小时前
Java里用Stream.parallel()翻车实录,这性能还不如单线程
前端·人工智能·后端
wangchunyu1145 小时前
JavaScript 零基础入门教程
前端
hanchenxing5 小时前
前端异步任务三方案:Celery vs Redis Stream vs BullMQ 实战对比消息队列
前端·数据库·redis·异步任务·方案对比