React框架运行主流程
1.JSX是JS语言的扩展,被babel编译后,会转换成React.creatElement(),这个方法返回的是一个虚拟DOM。
2.将虚拟DOM渲染到真实DOM的方法是ReactDom.render()。
 
在React的组件生命周期中,render是灵魂,它创建一个虚拟Dom;生命周期方法是躯干,负责事件的承载。
组件挂载
1.constructor()初始化state数据
2.componentWillMount()
3.render()
4.componentDidMount()
 
组件的更新
通过调用setState,生成一个新的VMDom, 新的VMDom与旧的VMDom相比,生成一个差异对象,然后遍历差异对象,更新真实Dom。
组件的更新路径有两条:
如果是父组件主动触发的,走上面那条线,会调用componentWillReceiveProps()
如果是组件内部的state状态变化触发的,走右边那条组件自更新路线。
公共路线:
1.shouldComponentUpdate()
2.componentWillUpdate()
3.render()
4.componentDidUpdate()
 
组件的卸载
组件的卸载只有一条方法的调用:
1.componentWillUnMount()
 
setState更新数据机制
1.setState是异步任务更新的,所以在setState后面做同步数据获取拿到的数据是之前的值。
2.连续调用多次setState,只会触发一次重新渲染,原因是React内部会合并连续的setState调用,提高刷新性能。
连续两次this.setState,同步获取的this.state.count是没有修改前的,连续2次的this.setState是无效的,在更新前会做合并,只有一次是有效的。
console.log("更新前:",this.state.count)
this.setState({
count: this.state.count + 1
})
console.log("更新后1:",this.state.count)
this.setState({
count: this.state.count + 1
})
console.log("更新后2:",this.state.count)
推荐使用第二种
通过传入箭头函数,拿箭头函数中的state参数,此参数表示最新的state值,所以虽然下面的
this.setState是异步方法,但是连续的2次调用,对state的修改是有序的,最终的结果是修改2次的结果
//state:最新的状态,props:最新的props
this.setState((state, props)=>{
return {
count: state.count + 1
}
})
console.log("更新后1:",this.state.count)
this.setState((state, props)=>{
return {
count: state.count + 1
}
})
console.log("更新后2:",this.state.count)
this.setState的第二个参数是回调函数,表示在状态更新完成后并且DOM渲染完成后,立即回调。
this.setState({
count: this.state.count + 1
},() => {
console.log("状态更新后,DOM页面渲染后:", this.state.count)
})
JSX的转换流程
 
 
1.代码中用jsx写的ele元素
const ele = <h2 id={"title"}>标题</h2>
2.被babel转换器转换后的React语句
React.createElement("h2", {id:"title"}, React.createContext("标题"))
3.React底部对ele元素的底层实现,是一个简单的js对象
$$typeof: Symbol(react.element)
key: null
props:
children: "标题"
id: "title"
[[Prototype]]: Object
ref: null
type: "h2"
_owner: null
_store: {validated: false}
_self: undefined
_source: {fileName: '/Users/zhoufei/Documents/React/web/my-app/src/my-src/Principle.js', lineNumber: 5, columnNumber: 13}
[[Prototype]]: Object
React的UI刷新机制
setState会触发刷新,触发流程分2步
1.更新状态数据
2.刷新UI
第二步的刷新UI是局部递归刷新的。
比如点击了页面中的子组件B,那么只会在子组件B和其子孙组件触发UI刷新,其他的兄弟组件和父组件是不刷新的。
React组件性能优化
1.减轻state
2.组件避免不必要的刷新
减轻state
state的修改会触发渲染,如果变量与渲染无关,那么就不要放在state中,放到this的成员变量中就可以了。
比如创建一个定时器,将定时器id放到this.timerID上。
组件避免不必要的刷新
根据组件的刷新机制,如果父组件刷新,那么它里面的所有子组件,子孙组件都要进行刷新,对于状态没有修改的情况下,重复刷新是浪费性能。可以在下面的方法判断是否需要进行刷新。
shouldComponentUpdate(nextProps, nextState, nextContext),返回false不进行刷新。
1.父组件内,判断this.state.count === nextState.count
shouldComponentUpdate(nextProps, nextState, nextContext) {
//this.state: 之前的状态
//nextState: 后面要修改的状态
if (this.state.count === nextState.count) {
return false
} else {
return true
} //优化
//return this.state.count !== nextState.coun
}

2.子组件内判断this.props.count !== nextProps.count

class Child extends React.Component{
shouldComponentUpdate(nextProps, nextState, nextContext) {
return this.props.count !== nextProps.count
} render() {
return (
<div>
子组件入参计数:{this.props.count}
</div>
);
}
}
3.使用纯组件React.PureComponent替换React.Component
PureComponent内部会自动实现方法shouldComponentUpdate,并对state和props分别比较,相同的话就返回false,取消渲染。
class PureChild extends React.PureComponent{
render() {
console.log("纯子组件 render")
return (
<div>
纯子组件入参计数:{this.props.count}
</div>
);
}
}
纯组件中的对比采用的是shallow compare,浅对比,如果是基本类型就是直接进行对比,如果是引用类型就对比其内存地址对比。
所以,如果是要对比对象或数组,那么就用...解包新建一个,这样会有新的内存地址。
class PureChild extends React.PureComponent{
state = {
obj: {
count: 0
},
list: [
"jack"
]
} hanleClick = () => {
//对象,数组的对比要采用新建的方式
this.setState({
count: {...this.state.obj, count: 1},
list: [...this.state.list, "lucy"]
})
} render() {
console.log("纯子组件 render")
return (
<div>
纯子组件入参计数:{this.props.count}
</div>
);
}
}
虚拟DOM与Diff算法
虚拟DOM:是一个js对象,用来描述你希望展示到屏幕上的内容。
虚拟DOM和Diff算法一起渲染流程:
1.根据state信息和jsx,在render后共同组成了一个虚拟DOM。
2.然后将虚拟DOM渲染render,变成真实的DOM。
3.当state信息变化时,React会生成一个新的VM DOM。
4.将新旧VM DOM进行对比,生成差异对象。
5.遍历差异对象,将差异对象更新到真实的DOM上。
 
render方法调用并不是说会刷新这个DOM树,而是生成了一个新的虚拟DOM,要开始diff了。
然后再将新生成的VM DOM与旧的VM DOM对比找到修改的差异对象,然后将这个差异对象渲染到屏幕上。
虚拟DOM的价值
虚拟DOM的最大价值不是让渲染性能更高了,而是让React脱离了浏览器的真实DOM而存在
只要能执行js的地方,都可以运行React。
所以React是面向虚拟DOM编程的,它可以将虚拟DOM根据不同的平台转换成不同的真实DOM。
IOS,安卓转换成原生控件,浏览器转换成页面标签。
Vue的虚拟DOM思想就是借鉴了React的虚拟DOM。
 
 
 
 

React框架运行机制的更多相关文章

  1. 解析gtest框架运行机制

    前言 Google test是一款开源的白盒单元测试框架,据说目前在Google内部已在几千个项目中应用了基于该框架的白盒测试. 最近的工作是在搞一个基于gtest框架搭建的自动化白盒测试项目,该项目 ...

  2. spring mvc 框架运行机制 + 数据绑定原理

    spring mvc 运行主要的组件: 1 前端控制器 (dispatchservlet) 相当于一个重要处理器,它用来调用其他功能模块来分工的效应一次请求,主要起调度的作用. 2. handler ...

  3. thinkphp5.0框架运行机制分享小结

    1 访问index.php 入口文件,定义应用目录,加载框架引导文件 <?php // [ 应用入口文件 ] // 定义应用目录 define('APP_PATH', __DIR__ . '/. ...

  4. 开源通用爬虫框架YayCrawler-框架的运行机制

    这一节我将向大家介绍一下YayCrawler的运行机制,首先允许我上一张图: 首先各个组件的启动顺序建议是Master.Worker.Admin,其实不按这个顺序也没关系,我们为了讲解方便假定是这个启 ...

  5. Web框架——XWAF的代码结构和运行机制(4)

    XWAF是一套基于Servlet和java反射技术的Web应用程序框架,它利用Servlet运行机制在服务器上加载和运行,接管客户端请求,依靠ServletRequest对象获取用户请求信息,使用Se ...

  6. pytest框架之rerunfailures失败重运行机制

    web自动化测试中,稳定性在整个测试运行中都至关重要,但不能保证测试脚本或者测试环境一直都能够稳定,它牵扯到诸多因素,在这里就不赘述,pytest框架相较于unittest的一大优势就在于拥有用例失败 ...

  7. 01_日志采集框架Flume简介及其运行机制

    离线辅助系统概览: 1.概述: 在一个完整的大数据处理系统中,除了hdfs+mapreduce+hive组成分析系统的核心之外,还需要数据采集.结果数据导出. 任务调度等不可或缺的辅助系统,而这些辅助 ...

  8. 基于Abp React前端的项目建立与运行——React框架分析

    基于Abp React前端的项目建立与运行 目录 基于Abp React前端的项目建立与运行 1 Abp项目配置 2 运行WebApi后端项目 2.1 创建C3D数据库,并且将数据库对应链接字符串替换 ...

  9. python的scrapy框架的使用 和xpath的使用 && scrapy中request和response的函数参数 && parse()函数运行机制

    这篇博客主要是讲一下scrapy框架的使用,对于糗事百科爬取数据并未去专门处理 最后爬取的数据保存为json格式 一.先说一下pyharm怎么去看一些函数在源码中的代码实现 按着ctrl然后点击函数就 ...

  10. 实时计算框架:Flink集群搭建与运行机制

    一.Flink概述 1.基础简介 Flink是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算.Flink被设计在所有常见的集群环境中运行,以内存执行速度和任意规模来执行计算.主要特性包 ...

随机推荐

  1. Codeforces Round #481 (Div. 3) 经典几道思维题

    A - AAA POJ - 3321 给你一颗树,支持两种操作 1.修改某一节点的权值 2.查询子树的权值(子树中节点的个数) 很显然可以用树状数组/线段树维护 B - BBB CodeForces ...

  2. Codeforces Round #721 (Div. 2) AB思维,B2博弈,C题map

    补题链接:Here 1527A. And Then There Were K 题目大意: 给一个正整数n,求最大的k,使得 \(n \& (n−1) \& (n−2) \& ( ...

  3. 前端科普系列(2):Node.js 换个角度看世界

    本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/fPNMaeNYgU3eJsh0SLMRRg作者:孔垂亮 [前端科普系列]往期精彩内容: &l ...

  4. ==和equals的区别和联系,StringBuffer和StringBuilder,clone方法

    ==和equals的区别和联系? ( 1)对于==,比较的是值是否相等 如果作用于基本数据类型的变量,则直接比较其存储的 "值"是否相等: 如果作用于引用类型的变量,则比较的是所指 ...

  5. 清洁低碳环保新能源,3D 光伏与光热发电站可视化

    前言 碳达峰.碳中和成为今年两会"热词",在国家政府工作报告中指出,扎实做好碳达峰.碳中和各项工作,制定 2030 年前碳排放达峰行动方案,优化产业结构和能源结构,实现低碳环保节能 ...

  6. 2022 开源之夏 | Serverless Devs 陪你“变得更强”

    Serverless 是近年来云计算领域热门话题,凭借极致弹性.按量付费.降本提效等众多优势受到很多人的追捧,各云厂商也在不断地布局 Serverless 领域.但是随着时间的发展,Serverles ...

  7. 十二、docker仓库

    系列导航 一.docker入门(概念) 二.docker的安装和镜像管理 三.docker容器的常用命令 四.容器的网络访问 五.容器端口转发 六.docker数据卷 七.手动制作docker镜像 八 ...

  8. 深度学习(六)——神经网络的基本骨架:nn.Module的使用

    一.torch.nn简介 官网地址: torch.nn - PyTorch 2.0 documentation 1. torch.nn中的函数简介 Containers:神经网络的骨架 Convolu ...

  9. oppo和海康嵌入式软件工程师面经总结

    目录 海康 一面(3.23,35min) 自我介绍 项目介绍 你做的这个项目遇到了那些问题,如何解决的? 移植uboot,只做了移植吗? 用的那个文件系统? 移植过程中,网卡驱动做了那些工作? 写过那 ...

  10. windows10测试时如何构造大图片(如超过8M+的图片)

    1.原图片(大小40k) 2. 选怎一个容量大的文件如视频文件8M+ 3.使用copy命令进行扩容(cmd命令行操作): copy test01.jpg /b + 8M.MP4 test01_8M.j ...