React 中 lazy, Suspense 以及错误边界(Error Boundaries)的使用

React 中 lazy, Suspense 以及错误边界(Error Boundaries)的使用

lazy

lazyreact 提供的组件懒加载的能力,在官方没有支持 lazy之前,在 react 中我们一般使用 react-loadable 来实现组件懒加载的能力,但是,lazy 并不支持 服务端渲染(SSR),所以在使用ssr的情况下,lazy 暂时不能使用

React.lazy 接受一个函数,这个函数内部调用 import() 动态导入。它必须返回一个 Promise,该 Promise 需要 resolve 一个 defalut exportReact 组件。

具体如何使用呢,看下面例子

  import React, { lazy } from 'react'

  const AppTitle = lazy(() => import('./title'))

  class App extends React.Component {
    render () {
      return (
       <AppTitle></AppTitle>
      )
    }
  }

  export default App

当我们把这段代码运行起来的时候,却发现程序报错了

  Error: A React component suspended while rendering, but no fallback UI was specified.

  Add a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.
      in Unknown (at lazy/index.jsx:8)
      in App (at src/index.js:7)

这个时候就需要 react 中内置的组件 Suspense 来配合使用,只需要将 Suspense 引入,然后将异步导入的组件包裹起来,同时也要指定 fallback 属性, 可以支持传入一段
jsx, 或者一个组件实例,类似 <Loading></Loading>

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

  const AppTitle = lazy(() => import('./title.jsx'))

  class App extends React.Component {
    render () {
      return (
        <Suspense fallback={<div>Loading</div>}><AppTitle></AppTitle></Suspense>
      )
    }
  }


  export default App

当我们使用 lazy 之后,我们可以打开 chromenetwork 然后选择 js 来观察 发起的请求,我们发现这个时候会出现 1.chunk.js 这种 数字开头的js文件,其实每个 .js 就对应我们每一个组件,当我们需要去 指定每个 异步组件 打包的js文件名时,我们只需要在 import() 函数中 添加 /* webpackChunkName: "title" */ 这段注释,webpack 在打包时,自动会将我们指定的名字作为文件名
在这里插入图片描述

在这里插入图片描述

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

  const AppTitle = lazy(() => import(/* webpackChunkName: "title" */'./title.jsx'))

  class App extends React.Component {
    render () {
      return (
        <Suspense fallback={<div>Loading</div>}><AppTitle></AppTitle></Suspense>
      )
    }
  }


  export default App

如果当一个组件异步加载下载js文件时,网络错误,无法下载 js 文件,那么 react 会表现出什么情况呢

  Error: Loading chunk 3 failed.
  (error: http://192.168.4.183:3000/static/js/title.chunk.js)

很明显,Suspense 无法处理这种错误情况, 在 react 中有一个 错误边界 (Error Boundaries)的概念,用来解决这种问题,它是利用了 react 生命周期的 componetDidCatch 方法来处理

有两种方式,一种是 生命周期 componentDidCatch 来处理错误,还有一种 是 静态方法 static getDerivedStateFromError 来处理错误,

官网的建议是

请使用 static getDerivedStateFromError() 渲染备用 UI ,使用 componentDidCatch() 打印错误信息。

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

  const AppTitle = lazy(() => import(/* webpackChunkName: "title" */'./title.jsx'))

  class App extends React.Component {
    state = {
      isError: false
    }

    static getDerivedStateFromError(error) {
      return { isError: true };
    }

    componentDidCatch (err, info) {
      console.log(err, info)
    }

    render () {
      if (this.state.isError) {
        return (<div>error</div>)
      }
      return (
        <div>
          <Suspense fallback={<div>Loading</div>}><AppTitle></AppTitle></Suspense>
        </div>
      )
    }
  }


  export default App

注意:使用 create-react-app 创建的项目,在开发环境,就算使用了 componentDidCatch 或者 getDerivedStateFromError,错误依然会被抛出,在 build 后,错误将会捕获,不会导致整个项目卸载

根据官方文档所说,在 react 16 以后,任何未被错误边界捕获的错误将会导致整个 React 组件树被卸载。 所以我们在开发项目时,需要去捕获错误边界的错误,并提供一个备用UI

github 代码地址

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React,你可以使用lazy函数和Suspense组件来实现按需加载路由组件。这样可以优化初始加载时间并提高应用程序的性能。下面是使用lazySuspense配置路由表的步骤: 1. 首先,确保你已经安装了React v16.6或更高版本,因为lazySuspense是在这个版本引入的。 2. 导入lazySuspense函数: ```jsx import React, { lazy, Suspense } from 'react'; ``` 3. 使用lazy函数来延迟加载你的路由组件。你可以将每个路由组件都包装在lazy函数: ```jsx const Home = lazy(() => import('./Home')); const About = lazy(() => import('./About')); ``` 在上述示例,Home和About组件将在需要时按需加载。 4. 在你的路由配置,将懒加载的组件包装在Suspense组件: ```jsx import { BrowserRouter, Route, Switch } from 'react-router-dom'; const App = () => { return ( <BrowserRouter> <Suspense fallback={<div>Loading...</div>}> <Switch> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> </Switch> </Suspense> </BrowserRouter> ); }; ``` 在上述示例,fallback属性定义了在组件加载时显示的加载界面。 5. 最后,确保你的应用程序使用BrowserRouter包装根组件。这样可以使路由器在整个应用程序起作用。 ```jsx import { BrowserRouter } from 'react-router-dom'; const RootApp = () => { return ( <BrowserRouter> <App /> </BrowserRouter> ); }; ``` 现在,当用户访问相应的路由时,React将自动按需加载路由组件。请注意,懒加载组件是异步加载的,因此在加载期间可能会显示加载界面或占位符。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值