React之lazy与suspense

本文深入探讨React的动态import、lazy和suspense特性。动态import提供运行时加载模块的能力,提升页面加载速度。lazy组件在需要时异步加载React模块,而suspense则在加载过程中提供占位UI。同时介绍了错误边界getDerivedStateFromError和componentDidCatch,用于捕获和处理子组件的错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态import

在说lazysuspense之前,还是先说说动态import这种语法。

import语句我们使用的很多,通常是import ... from '...'这样的写法,这样的写法也被称作是静态加载。

而所谓的动态import或者说动态加载,就是指在运行时加载。写法如下:

import('./test.js').then(test => {
    ...
});

可以发现,动态import实现了Promise规范,回调函数的test参数就是加载完成后的模块。

这么写有什么好处呢?一个页面中也许会有许多的逻辑代码并不需要在页面加载时加载,也许是在触发了某个事件如点击之后才需要加载。那么通过动态加载就可以实现这一点,好处在于可以加快页面加载的速度。

lazy

对于一段JS代码,我们可以在需要的时候通过动态import的方式异步加载,那么对于一个React模块,什么是“需要的时候”?到了这个时候又该怎么加载呢?

对于React模块,这个“需要的时候”自然就是要渲染它的时候,而想要在这个时候实现异步加载就需要使用React 16.6中新增的lazy方法了。

lazy是一个方法,它封装了“动态加载的过程”,如果对这句话不太明白,看下面的代码就能理解:

import React, { lazy, Component } from 'react';
const Later = lazy(() => import('./Later'));

上面代码中的Later是一个React组件,但它并不能被渲染,它只是一个“动态加载过程”的封装。它在要被渲染的时候就会去加载真正的Later组件。

lazy方法接受一个无参数的函数,函数必须执行动态import。

那是不是直接这样使用就可以了呢?

import React, { lazy, Component } from 'react';
const Later = lazy(() => import('./Later'));

export default class App extends Component {
  render() {
    return (
      <div> 
          <Later />  
      </div>
    );
  }
}

可以发现在浏览器中是会报错的:

在这里插入图片描述
出现这个报错就需要用到suspense了。

suspense

既然是动态加载,那么也就是说会有一个加载过程,那么在这个加载过程中就需要一个UI组件,来在等待过程中显示一些UI。

import React, { Component, lazy, Suspense } from 'react';

const Later = lazy(() => import('./Later'));
export default class App extends Component {
 render() {
   return (
     <div> 
       <Suspense fallback={<div>loading...</div>}>
         <Later />  
       </Suspense>
     </div>
   );
 }
}

这样就会在Later加载完成之前显示“loading…”字样。

suspense组件有一个fallback属性,它就是用来接收加载过程中显示的组件的。suspense内部是可以包裹多个组件的。

Error boundaries

Error boundaries,中文意为错误边界。我们希望部分UI的错误不会导致整个程序的崩溃,以及希望在错误发生时能够显示对应的UI。

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

如果一个 class 组件中定义了 static getDerivedStateFromError()componentDidCatch() 这两个生命周期方法中的任意一个(或两个)时,那么它就变成一个错误边界。当抛出错误后,请使用 static getDerivedStateFromError() 渲染备用 UI ,使用 componentDidCatch() 打印错误信息。

getDerivedStateFromError

此生命周期会在后代组件抛出错误后被调用。 它将抛出的错误作为参数,并返回一个值以更新 state。

注:getDerivedStateFromError() 会在渲染阶段调用,因此不允许出现副作用。 如遇此类情况,请改用 componentDidCatch()。

componentDidCatch

此生命周期在后代组件抛出错误后被调用。 它接收两个参数:

  • error —— 抛出的错误。
  • info —— 带有 componentStack key 的对象,其中包含有关组件引发错误的栈信息。

注:componentDidCatch() 会在“提交”阶段被调用,因此允许执行副作用。 它应该用于记录错误之类的情况。

import React, { Component } from 'react';

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

    static getDerivedStateFromError(err){
        return {hasError: true};
    }

    componentDidCatch(err, errinfo){
        console.log(err);
        console.log(errinfo);
    }

    render() {
        const { hasError } = this.state;
        if(hasError){
            return <div>Something wrong!!!</div>
        }
        return this.props.children;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值