React.Suspense和React.lazy代替react-loadable实现路由懒加载

本文主要是介绍React.Suspense和React.lazy代替react-loadable实现路由懒加载,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、react-loadable使用

import { RouteConfig } from 'react-router-config';
import Loadable from 'react-loadable'
import React from 'react';interface CustomRouteConfig extends RouteConfig {}const routes: CustomRouteConfig[] = [{path: '/',component: Loadable({loader: () => import('../layout'),loading: () => React.createElement('span', {}, 'loading'),}),routes: [{path: '/keyof',component: Loadable({loader: () => import('../pages/Keyof'),loading: () => React.createElement('span', {}, 'loading')})},{path: '/match',component: Loadable({loader: () => import('../pages/Match'),loading: () => React.createElement('span', {}, 'loading')})},{path: '/match/:id',component: Loadable({loader: () => import('../pages/Match'),loading: () => React.createElement('span', {}, 'loading')})},{path: '/abort',component: Loadable({loader: () => import('../pages/AbortController'),loading: () => React.createElement('span', {}, 'loading')})},]}
]export default routes

看看Loadable是如何实现懒加载的:

// Loadable
function Loadable(opts) {return createLoadableComponent(load, opts);
}// load函数,用于获取promise对象中的组件
function load(loader) {var promise = loader();var state = {loading: true,loaded: null,error: null};state.promise = promise.then(function (loaded) {state.loading = false;state.loaded = loaded;return loaded;}).catch(function (err) {state.loading = false;state.error = err;throw err;});return state;
}// createLoadableComponent
function createLoadableComponent(loadFn, options) {var _class, _temp;var res = null;function init() {if (!res) {res = loadFn(opts.loader);}return res.promise;}return _temp = _class = function (_React$Component) {_inherits(LoadableComponent, _React$Component);function LoadableComponent(props) {_classCallCheck(this, LoadableComponent);var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));_this.retry = function () {_this.setState({ error: null, loading: true, timedOut: false });res = loadFn(opts.loader);_this._loadModule();};init();_this.state = {error: res.error,pastDelay: false,timedOut: false,loading: res.loading,loaded: res.loaded};return _this;}LoadableComponent.prototype._clearTimeouts = function _clearTimeouts() {clearTimeout(this._delay);clearTimeout(this._timeout);};LoadableComponent.prototype.render = function render() {if (this.state.loading || this.state.error) {return React.createElement(opts.loading, {isLoading: this.state.loading,pastDelay: this.state.pastDelay,timedOut: this.state.timedOut,error: this.state.error,retry: this.retry});} else if (this.state.loaded) {return opts.render(this.state.loaded, this.props);} else {return null;}};return LoadableComponent;}(React.Component), _class.contextTypes = {loadable: PropTypes.shape({report: PropTypes.func.isRequired})}, _temp;
}

Loadable是一个高阶组件(hoc),在执行Loadable时会执行createLoadableComponent函数,在createLoadableComponent函数中会执行loader函数得到一个promise对象,这个promise对象包含的是导入的组件,最后会返回一个LoadableComponent组件,该组件的render方法会渲染导入的组件,继而完成组件加载。

2、使用React.Suspense、React.lazy

让我们看看React文档对React.lazy的说法:

React.lazy必须通过调用动态的 import()加载一个函数,此时会返回一个 Promise,并解析( resolve)为一个带有包含React组件的默认导出的模块。

使用React.Suspense可以优化懒加载前的交互,fallback 属性接受任何在组件加载过程中你想展示的 React 元素。你可以将 Suspense 组件置于懒加载组件之上的任何位置。你甚至可以用一个 Suspense 组件包裹多个懒加载组件。React.lazy加载的组件只能在<React.Suspense>组件下使用。

import { RouteConfig } from 'react-router-config';
import Loadable from 'react-loadable'
import React from 'react';
import LoadComp from '../components/Loading';
import Layout from '../layout';interface CustomRouteConfig extends RouteConfig {}const routes: CustomRouteConfig[] = [{path: '/',// 如果父级和子级路由都是用lazy、suspense会导致子级路由不会渲染// component: LoadComp(React.lazy(() => import('../layout'))),component: Layout,routes: [{path: '/keyof',component: LoadComp(React.lazy(() => import('../pages/Keyof'))),},{path: '/match/:id',component: LoadComp(React.lazy(() => import('../pages/Match'))),},{path: '/abort',component: LoadComp(React.lazy(() => import('../pages/AbortController'))),},]}
]export default routes
// loadComp高阶组件
import React from 'react';
import Loader from 'react-loader-spinner';const loadComp = (Com: React.LazyExoticComponent<any>) => {return class LoadComp extends React.Component<any, any> {render() {return (<React.Suspense fallback={<Loader type="Puff" color="#00BFFF" height={100} width={100} timeout={3000}/>}><Com /></React.Suspense>)}}
}export default loadComp;

3、替换前后对比

对比react-loadable,React.Suspense还是有一些不足。

  1. 加载组件缺少delay参数,不能解决请求快速完成时的"闪烁"问题(即使加载模块只需要几毫秒的时间, fallback也会被执行,就上述代码来说,也就是 Spinner 会闪烁一下),需要自己封装
  2. 没有内置的加载错误处理方法,需要自己去处理
  3. react-loadable有预加载支持,React.Lazy没有

仍然推荐使用react-loadable来异步加载组件,暂时不用React.Suspense。

这篇关于React.Suspense和React.lazy代替react-loadable实现路由懒加载的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/508760

相关文章

C#实现将Excel表格转换为图片(JPG/ PNG)

《C#实现将Excel表格转换为图片(JPG/PNG)》Excel表格可能会因为不同设备或字体缺失等问题,导致格式错乱或数据显示异常,转换为图片后,能确保数据的排版等保持一致,下面我们看看如何使用C... 目录通过C# 转换Excel工作表到图片通过C# 转换指定单元格区域到图片知识扩展C# 将 Excel

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

基于Java实现回调监听工具类

《基于Java实现回调监听工具类》这篇文章主要为大家详细介绍了如何基于Java实现一个回调监听工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录监听接口类 Listenable实际用法打印结果首先,会用到 函数式接口 Consumer, 通过这个可以解耦回调方法,下面先写一个

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Qt中QGroupBox控件的实现

《Qt中QGroupBox控件的实现》QGroupBox是Qt框架中一个非常有用的控件,它主要用于组织和管理一组相关的控件,本文主要介绍了Qt中QGroupBox控件的实现,具有一定的参考价值,感兴趣... 目录引言一、基本属性二、常用方法2.1 构造函数 2.2 设置标题2.3 设置复选框模式2.4 是否

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法

《springboot整合阿里云百炼DeepSeek实现sse流式打印的操作方法》:本文主要介绍springboot整合阿里云百炼DeepSeek实现sse流式打印,本文给大家介绍的非常详细,对大... 目录1.开通阿里云百炼,获取到key2.新建SpringBoot项目3.工具类4.启动类5.测试类6.测

pytorch自动求梯度autograd的实现

《pytorch自动求梯度autograd的实现》autograd是一个自动微分引擎,它可以自动计算张量的梯度,本文主要介绍了pytorch自动求梯度autograd的实现,具有一定的参考价值,感兴趣... autograd是pytorch构建神经网络的核心。在 PyTorch 中,结合以下代码例子,当你

SpringBoot集成Milvus实现数据增删改查功能

《SpringBoot集成Milvus实现数据增删改查功能》milvus支持的语言比较多,支持python,Java,Go,node等开发语言,本文主要介绍如何使用Java语言,采用springboo... 目录1、Milvus基本概念2、添加maven依赖3、配置yml文件4、创建MilvusClient

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的