react 日历组件_anujs1.5.1支持React.Suspense与lazy

React16是一个实验版本,除了测试它的新fiber架构外,还添加了大量新功能。其他React.Suspense与React.lazy就是重磅中的重磅。

随着前端的APP化,不断集成功能,页面越来越大,bundle size以MB为单位,我们需要拆分代码,实现动态化加载非首屏功能。比日历,城市选择器,评论组件等等。

动态加载,在javascript模块加载规范中已经有草案,并且被webpack, rollup所支持

import('../components/Hello').then(Hello => {console.log(<Hello />);
});

相当于(setTimeout模拟异步加载组件):

new Promise(resolve =>setTimeout(() =>resolve({// 来自另一个文件的函数式组件default: function render() {return <div>Hello</div>}}),3000)
).then(({ default: Hello }) => {console.log(<Hello />);
});

React16提供了lazy组件实现这个功能

    var {lazy, Suspense} = React;var OtherComponent = lazy(()=>{return new Promise(resolve =>setTimeout(() =>resolve({default: function Hello() { //export defaultreturn <div>Hello</div>}}),3000))});

上面只是一个方便大量测试的例子,实际需要将 <div>Hello</div> 放到一个文件中,使用import()语法引进来,即

 const OtherComponent = React.lazy(() => import('./OtherComponent')); 

OtherComponent.js的源码

export default function Hello(){return <div>Hello</div>
}

接着我们实现将动态功能加进组件树,就是所谓的条件渲染。这个功能由React.Suspense提供。在框架不提供这功能的情况下,我们需要找一个父组件,将这组件动态挂上去:

class MyComponent extends Component {constructor() {super();this.state = {};// 动态加载import('./OtherComponent').then(({ default: OtherComponent }) => {this.setState({ OtherComponent });});}render() {const { OtherComponent } = this.state;return (<div>{/* 条件渲染 */}{ OtherComponent && <OtherComponent /> }</div>);}
}

但光是这样还是不行的,因为单纯的动态加载,会引起页面抖动,我们需要loading将这个突兀的显示给缓解一下。于是这render需要改成

render() {const { OtherComponent } = this.state;return (<div>{OtherComponent ? <OtherComponent />: <Loading />}</div>);}

如果有了Suspense组件,我们就简单了,不需要入侵已有的组件,并且有地方挂这个loading。

<Suspense fallback={<Loading />}><OtherComponent /></Suspense>

需要注意的是,lazy组件外面必须包着一个Suspense组件。从框架层面对用户体验提出了强制要求。

下面是一个完整的例子

<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width">
<!--<script src="https://cdn.bootcss.com/react/16.7.0-alpha.2/umd/react.development.js"></script><script src="https://cdn.bootcss.com/react-dom/16.7.0-alpha.2/umd/react-dom.development.js"></script>
--><script src="./dist/React.js"></script> <script type='text/javascript' src="./lib/babel.js"></script></head><body><div id='root' class="root"></div><script type='text/babel'>var { lazy, Suspense } = React;
var OtherComponent = lazy(() => {return new Promise(resolve =>setTimeout(() =>resolve({default: function render(props) {//export defaultreturn <div>Hello,{props.name}</div>;}}),3000));
});
var valueRef = React.createRef()
class App extends React.Component {constructor(props){super(props)this.state = {name: "ruby"}}updateName(){var  name = valueRef.current.value;this.setState({name})}render() {return (<div><p><input ref={valueRef} onChange={this.updateName.bind(this)}  value={this.state.name} />{new Date-0}</p><Suspense  fallback={<div>loading...</div>}><OtherComponent name={this.state.name} /></Suspense></div>);}
}ReactDOM.render(<App />, document.getElementById("root"));</script></html>

最后说一下实现,React官方是通过lazy组件主动抛错,给上面Suspense组件接住的hack方式实现的

https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberWorkLoop.js#L907-L1057

029ec7eb298d2a264a3dc63e673f1a1d.png

lazy组件被读取时

https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberLazyComponent.js

1031cce49cf337eb754a4986c6053a82.png

React官方投入了近500行代码实现的,

再看一下anujs如何实现的。

anujs的Suspense是异常简单,就是一个虚拟组件,甩手掌柜,总是渲染它的孩子。它只负责挂loading。

function Suspense(props){return props.children
}export {Suspense
}

lazy组件就是将用户函数,再包一层,封到一个LazyComponent组件中,它会根据用户的promise决定是返回上层的suspense组件的fallback属性,还是延期加载回来的组件。

import { miniCreateClass, isFn, get } from "react-core/util";
import { Component } from "react-core/Component";
import { createElement } from "react-core/createElement";
import { Suspense } from "./Suspense";var LazyComponent = miniCreateClass(function LazyComponent(props, context) {this.props = props;this.context = context;this.state = {component: null,resolved: false}var promise = props.render();if(!promise || !isFn(promise.then)){throw "lazy必须返回一个thenable对象"}promise.then( (value) =>this.setState({component: value.default,resolved:  true}))}, Component, {fallback(){//返回上层Suspense组件的fallback属性var parent = Object(get(this)).returnwhile(parent){if( parent.type === Suspense){return parent.props.fallback}parent = parent.return}throw "lazy组件必须包一个Suspense组件"},render(){return this.state.resolved ? createElement(this.state.component) : this.fallback()}
});
function lazy(fn) {return function(){return createElement(LazyComponent, {render: fn})}
}
export {lazy
}

最后欢迎大家使用anujs 。一个迷你React框架,支持react16 的所有新特性,可以用于小程序中。

RubyLouvre/anu​github.com
5e1be538ea4fbf9ea05b1e78c51eae2f.png
npm i anujs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334120.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

packt_Packt发行的$ 5 Java编程书籍:精通Java 9,Java 9高性能

packt你好&#xff0c;极客&#xff01; 今天&#xff0c;我们为您带来一些激动人心的消息&#xff01; Java Code Geeks和Packt联手为您提供广泛的书籍库每周折扣。 本周&#xff0c;我们提供Java相关书籍的折扣&#xff0c;以帮助您了解和掌握Java。 他们全都打折到每本书5…

redis 发布订阅实际案例_【赵强老师】Redis的消息发布与订阅

欢迎关注赵强老师微信公众号&#xff1a;myitshareRedis 作为一个publish/subscribe server&#xff0c;起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向Redis server订阅自己感兴趣的消息类型&#xff0c;当发布者通过publish命令向Redis server发送特定类型…

上海大学计算机考研数一数二,2021年考研成绩出来了!上海大学数二人均135+,“神仙打架”现场...

原标题&#xff1a;2021年考研成绩出来了&#xff01;上海大学数二人均135&#xff0c;“神仙打架”现场文/跳跳妈妈谈教育2000年代初期&#xff0c;电视上流行这样一句话&#xff0c;“二十一世纪什么最珍贵&#xff1f;人才&#xff01;”时间如长河不断流逝&#xff0c;步入…

计算机配置界面在那,在哪里设置关机画面?设置为原来的经典界面?

电脑故障现象&#xff1a;我用的系统是winxp&#xff0c;关机出现的画面是那种下拉式菜单“注销、重启、关机、取消”&#xff0c;我想用的不是这种下拉式菜单&#xff0c;是并列图标那种&#xff0c;请问在哪里设置&#xff1f;(电脑入门到精通网 www.58116.cn)一般解决方法&a…

程序代码移植和烧录需要注意什么_购买建站模板需要注意什么问题

购买建站模板需要注意什么问题?现在市面上出现的建站工具质量参差不齐&#xff0c;但是如此多的建站模板&#xff0c;应该选择哪个呢&#xff1f;如此多的建站工具平台应该怎么样选择呢&#xff1f;这里我们来聊一聊。北京网站建设公司—东浩联创现在非常多站长都会购买一些定…

java 方法 示例_Java 9示例–收集的工厂方法–创建不可修改的列表,集合和映射...

java 方法 示例大家好&#xff0c;这是我在该博客上发表的有关Java 9功能的第一篇文章&#xff0c;今天您将了解我最喜欢的功能“收集的工厂方法” &#xff0c;它是JEP 269的一部分。JEP代表JDK增强建议。 如果您曾经在Groovy或Kotlin工作过&#xff0c;那么您就会知道使用集合…

高一计算机算法教案,高一信息技术第六章“第一节程序设计的基本方法”教案设计...

一、教学目标1&#xff0e;理解算法的概念&#xff1b;2&#xff0e;知道两种算法的描述方法—语言描述法和流程图的区别3&#xff0e;能初步利用算法解决简单的问题。4&#xff0e;培养学生的理论联系实际能力和动手操作能力。二、教学重难点1&#xff0e;重点&#xff1a;算法…

openshift安装_云幸福–如何在几分钟内安装新的OpenShift Container Platform 3.7

openshift安装此安装需要安装Red Hat Middleware产品流&#xff08;预配置的容器选项&#xff09;以及所有其他功能&#xff0c;例如源容器&#xff0c;映像容器和.Net Core容器。自OpenShift容器平台发布以来&#xff0c;我一直希望提供一个简单的方法。 &#xff0c;完全配置…

简单的计算机程序代码,优秀程序员通过简单代码,窥探电脑编程中强大的数组操作功能...

优秀程序员通过简单代码&#xff0c;窥探电脑编程中强大的数组操作功能。编程语言中&#xff0c;数组是一个非常重要的概念&#xff0c;也是一种很常用的类型。本文中通过javascript语言的代码实例&#xff0c;展现编程中数组的魅力。在javascript语言中&#xff0c;数组Array类…

java 示例_功能Java示例 第3部分–不要使用异常来控制流程

java 示例这是称为“ Functional Java by Example”的系列文章的第3部分。 我在本系列的每个部分中开发的示例是某种“提要处理程序”&#xff0c;用于处理文档。 在前面的部分中&#xff0c;我从一些原始代码开始&#xff0c;并应用了一些重构来描述“什么”而不是“如何”。…

win7 计算机定时关机脚本,win7怎么定时关机?win7定时关机设置两种方法

当我们在操作电脑的时候&#xff0c;有时会有需要定时关机&#xff0c;或者不在电脑前操作是需要过段时间自动关机&#xff0c;但是Win7系统没有自带的定时关机软件&#xff0c;很多电脑用户又不喜欢安装第三方软件来完成该操作。那么win7怎么定时关机&#xff1f;本文为大家介…

java面试spring_针对Java程序员的二十大Spring REST面试问题答案

java面试spring大家好&#xff0c;过去两周来&#xff0c;我一直在与Spring教程共享一些REST&#xff0c;今天&#xff0c;我将向申请Web开发人员角色的Java开发人员共享一些常见的Spring和REST采访问题。 由于Spring Framework是用于开发Java Web应用程序和RESTful Web Servic…

springboot jwt token前后端分离_「转」七个开源的 Spring Boot 前后端分离项目,建议收藏加转载...

其实前后端分离本身并不难&#xff0c;后段提供接口&#xff0c;前端做数据展示&#xff0c;关键是这种思想。很多人做惯了前后端不分的开发&#xff0c;在做前后端分离的时候&#xff0c;很容易带进来一些前后端不分时候的开发思路&#xff0c;结果做出来的产品不伦不类&#…

联想办公计算机,办公娱乐两不误!联想这些笔记本电脑不容错过

【PConline 海选导购】随着技术的进步&#xff0c;如今的笔记本电脑性能越来越强&#xff0c;尤其是笔记本电脑携带更加方便&#xff0c;可以让你摆脱使用场景的限制&#xff0c;能随时随地畅玩游戏或者进行日常办公&#xff0c;有着台式机无可比拟的优势&#xff0c;因此&…

ftp主要完成与远程计算机的连接,2015计算机三级《网络技术》复习重点:远程登录服务和FTP服务...

2015计算机三级《网络技术》复习重点&#xff1a;远程登录服务和FTP服务一、远程登录服务(TCP连接)(TCP的23端口服务)1、远程登录协议用户使用Telnet命令&#xff0c;使自己的计算机成为远程计算机的一台仿真终端。远程登录允许任意类型的计算机之间进行通信&#xff0c;具体实…

度量空间的应用_使用Dropwizard度量标准监视和测量无功应用

度量空间的应用在上一篇文章中&#xff0c;我们创建了一个简单的索引代码&#xff0c;该代码可以对ElasticSearch进行数千个并发请求。 监视系统性能的唯一方法是老式的日志记录语句&#xff1a; .window(Duration.ofSeconds(1)) .flatMap(Flux::count) .subscribe(winSize -&…

rust的权限柜怎么做_潍坊装修知识~二胎家庭不做上下铺,把两张床靠墙放,中间做收纳柜,你感觉怎么样?...

如今装修最受关注也最让人头疼的就是儿童房装修了&#xff0c;身边二胎家庭、双胞胎家庭也是越来越多&#xff0c;如果户型小&#xff0c;再面对那只有几十平的小户型&#xff0c;2个孩子无法避免的要挤一间卧室&#xff01;所以对于儿童床的摆放和收纳该如何合理安排呢&#x…

java方法示例注释 @_Java 8中的功能接口是什么? @功能注释和示例

java方法示例注释 函数接口是Java 8最重要的概念之一&#xff0c;实际上为lambda表达式提供了动力&#xff0c;但是许多开发人员没有首先了解函数接口在Java 8中的作用就花了很多精力来理解它&#xff0c;并花时间学习lambda表达式和Stream API。除非您知道什么是功能接口以及l…

sql 除法_七天学会SQL-04SQL复杂查询

一、视图&#xff08;以下SQL操作都在Navicat客户端下操作&#xff09;1、什么是视图&#xff1f;1.是什么&#xff1f; 视图存放sql查询语句&#xff0c;使用视图时&#xff0c;会运行视图里的sql查询语句创造出一张临时表&#xff1b;如需频繁使用一段sql查询语句时可将该查询…

r中rep_Spring中@ Component,@ Service,@ Controller和@Repository之间的区别

r中rep在了解Spring框架中Repository Component &#xff0c; Service Controller &#xff0c; Repository Controller和Repository批注之间的区别之前&#xff0c;了解Component批注在Spring中的作用很重要。 在Spring的初始发行期间&#xff0c;所有bean都用于在XML文件中声…