浅谈React工作原理
浅谈React工作原理:https://www.cnblogs.com/yikuu/p/9660932.html
Reactjs 起源于Facebook内部项目,是一个用来构建用户界面的 javascript 库,相当于MVC架构中的V层框架,与市面上其他框架不同的是,React 把每一个组件当成了一个状态机,组件内部通过state来维护组件状态的变化,当组件的状态发生变化时,React通过虚拟DOM技术来增量并且高效的更新真实DOM。本文将对React 的这些特点进行简单的介绍。
一个简单的React组件 —— HelloReact
考虑到有的同学还不曾了解过React,我们先来写一个简单的React组件,让大家一睹为快!

1 // 创建一个HelloReact组件
2
3 var HelloReact = React.createClass({
4
5 render:function(){
6
7 return (
8
9 <div>
10
11 Hello React!
12
13 </div>
14
15 )
16
17 }
18
19 });
20
21 // 使用HelloReact组件
22
23 ReactDOM.render(
24
25 <HelloReact />,
26
27 document.querySelector('body')
28
29 )

这样就定义了一个React组件,当然要运行这段代码是有条件的,需要引入React库,还需要引入JSX语法转换库,这里不多说了,这些基础的东西还需要各位亲自实践才好!
React 核心技术 —— 虚拟DOM(Virtual DOM)
在前端开发的过程中,我们经常会做的一件事就是将变化的数据实时更新到UI上,这时就需要对DOM进行更新和重新渲染,而频繁的DOM操作通常是性能瓶颈产生的原因之一,有时候我们会遇到这样一种尴尬的情况:比如有一个列表数据,当用户执行刷新操作时,Ajax会重新从后台请求数据,即使新请求的数据和上次完全相同,DOM也会被全部更新一遍并进行重新渲染,这样就产生了不必要的性能开销。
React为此引入了虚拟DOM(Virtual DOM)机制:对于每一个组件,React会在内存中构建一个相对应的DOM树,基于React开发时所有的DOM构造都是通过虚拟DOM进行,每当组件的状态发生变化时,React都会重新构建整个DOM数据,然后将当前的整个DOM树和上一次的DOM树进行对比,得出DOM结构变化的部分(Patchs),然后将这些Patchs 再更新到真实DOM中。整个过程都是在内存中进行,因此是非常高效的。借用一张图可以清晰的表示虚拟DOM的工作机制:

React 生命周期
React 把每个组件都当作一个状态机来维护和管理,因此每个组件都拥有一套完整的生命周期,大致可以分为三个过程:初始化、更新和销毁。生命周期的每一个过程都明确的反映了组件的状态变化。对于开发来说就能很容易的把握组件的每个状态,不同的状态时期做对应的事情,互不干扰。以下是和组件生命周期相关的几个方法:

1 getDefaultProps //创建组建
2
3 getInitialState //实例化状态
4
5 componentWillMount //挂载前
6
7 componentDidMount //挂载后
8
9 componentWillReceiveProps //属性被改变时
10
11 shouldComponentUpdate //是否更新
12
13 componentWillUpdate //更新前
14
15 componentDidUpdate //更新后
16
17 componentWillUnmount //销毁前

对于外部系统来说,组件是一个独立存在的封闭系统,内部的逻辑被隐藏,只对外暴露传递数据的接口,而React为我们提供了两种方式来向组件传递数据,即 props 和 state。
props 是在调用 ReactDOM.render() 时通过标签属性xxx传递,然后通过 this.props.xxx 来获取,getDefaultProps 允许你为组件设置一个默认的props值,在没有传递props的情况下显示默认值。

1 // 创建HelloReact组件
2
3 var HelloReact = React.createClass({
4
5 /**
6
7 * 当设置props的默认值 当没有传递时显示默认值
8
9 * @return {}
10
11 */
12
13 getDefaultProps:function(){
14
15 return {
16
17 data:"暂无数据"
18
19 }
20
21 },
22
23 render:function(){
24
25 return (
26
27 <div>
28
29 //显示data,当props发生变化时会自动更新
30
31 {this.props.data}
32
33 </div>
34
35 )
36
37 }
38
39 });//传递props属性data
40
41 ReactDOM.render(
42
43 <HelloReact data={"Hello React!"} />,
44
45 document.querySelector('body')
46
47 )

和 props 不同的是,state不能通过外部传递,因此在使用state之前,需要在 getInitialState 中为state设置一个默认值,然后才能通过 this.state.xxx 来访问,当组件被挂载完成时,触发 componentDidMount 方法,我们可以在这里通过Ajax请求服务器数据,然后再通过 setState() 把state的值设置为真实数据。

// 创建HelloReact组件
var HelloReact = React.createClass({
/**
* 设置组件的初始值
* @returns {{data: Array, msg: string}}
*/
getInitialState:function(){
return {
data:"数据加载中..." //初始值为[]
}
},
/**
* 挂载后首次加载数据
*/
componentDidMount:function(){
this.requestData();//请求数据
},
/**
* 请求后台数据
*/
requestData:function(){
$.ajax({
url:'xxxx.ashx',
data:{},
success:function(data){
this.setState({
data:data //通过setState()更新服务器数据
})
}
}.bind(this))
},
render:function(){
return (
<div>
{this.state.data}
</div>
)
}
});
ReactDOM.render(
<HelloReact />,
document.querySelector('body')
)

更新
props属性是只读的,如果想要改变props的值,只能通过重新调用render()来传递新的props,但要注意的是,重新执行render()组件不会被重新挂载,而是通过虚拟DOM技术进行增量更新和渲染,这时还会触发 componentWillReceiveProps 方法,并将新的props作为参数传递,你可以在这里对新的props进行处理。
相比props,state天生就是用来反映组件状态的,因此它的值是可以被改变的,当state的值被改变时,通过setState就可以改变state的值,React同样也是采用虚拟DOM技术来计算需要被更新的部分,而不是牵一发动全身的更新和渲染。
当 props 和 state 的状态发生变化后,组件在即将更新之前还会触发一个叫 shouldConponentUpdate 的方法,如果 shouldConponentUpdate 返回的是 true,不管props和state 的值和上一次相比有没有变化,React 都会老老实实的进行对比。此时,如果你确定以及肯定两次数据没有变化,那就让 shouldConponentUpdate 返回 false,React就不会进行diff了,更不会重新渲染了。瞬间省去了diff的时间。
销毁
当组件从DOM中被移除时,React会销毁之。在销毁之前,细心的React还触发 componentWillUnmount 来通知你,看你最后有没有什么话想对这个即将销毁的组件说,当然你没什么事就不用了。
什么时候用props,什么时候用state
我们已经知道可以通过props和state两种方式向组件传递数据,props是只读的不能被改变,而 state 是用来反映一个组件的状态,是可以改变的。因此,当组件所需要的数据在调用时是已经确定的,不频繁发生变化的,就可以使用props来传递,相反,当组件所需要的数据在调用时不能确定,需要等待异步回调时才能确定,比如ajax请求数据,input的onchange事件,这时就需要使用state来记录和改变这些值得变化。
浅谈React工作原理的更多相关文章
- [iOS]浅谈NSRunloop工作原理和相关应用
一. 认识NSRunloop 1.1 NSRunloop与程序运行 那么具体什么是NSRunLoop呢?其实NSRunLoop的本质是一个消息机制的处理模式.让我们首先来看一下程序的入口——main ...
- 浅谈React
浅谈react react是什么?其官网给出了明确定义:A JavaScript library for building user interfaces,一个用于构建用户界面的JavaScript库 ...
- 【转】浅谈React、Flux 与 Redux
本文转自<浅谈React.Flux 与 Redux>,转载请注明出处. React React 是一个 View 层的框架,用来渲染视图,它主要做几件事情: 组件化 利用 props 形成 ...
- 浅谈html运行原理
浅谈HTML运行原理,所谓的HTML简单的来说就是一个网页,虽然第一节就讲html原理可能大家会听不懂,就当是给一个初步印象把,至少大概知道一个网页的运行流程是怎样的,下面上一张图: 大致的一个htm ...
- 浅谈C++编译原理 ------ C++编译器与链接器工作原理
原文:https://blog.csdn.net/zyh821351004/article/details/46425823 第一篇: 首先是预编译,这一步可以粗略的认为只做了一件事情,那就 ...
- 浅谈React数据流管理
引言:为什么数据流管理如此重要?react的核心思想就是:UI=render(data),data就是我们说的数据流,render是react提供的纯函数,所以用户界面的展示完全取决于数据层.这篇文章 ...
- 浅谈React编程思想
React是Facebook推出的面向视图层开发的一个框架,用于解决大型应用,包括如何很好地管理DOM结构,是构建大型,快速Web app的首选方式. React使用JavaScript来构建用户界面 ...
- 浅谈React受控与非受控组件
背景 React内部分别使用了props, state来区分组件的属性和状态.props用来定义组件外部传进来的属性, 属于那种经过外部定义之后, 组件内部就无法改变.而state维持组件内部的状态更 ...
- 浅谈P2P终结者原理及其突破
P2P终结者按正常来说是个很好的网管软件,但是好多人却拿它来,恶意的限制他人的流量,使他人不能正常上网,下面我们就他的功能以及原理还有突破方法做个详细的介绍! 我们先来看看来自在网上PSP的资料:P2 ...
随机推荐
- oracle 循环的一种写法
for v_n in( select bb.temNum, bb.LOANTYPE from (select decode(bns.assignstate, '{016D68F9-719B-4EFC- ...
- 《剑指offer》算法题第三天
今日题目: 斐波那契数列 青蛙跳台阶问题(及其变种:变态跳台阶) 矩形覆盖 旋转数组的最小数字 矩阵中的路径 机器人的运动范围 细心的同学会发现,第1,2,3题其实对应的是<剑指>书上的同 ...
- 论文阅读:FlowBlaze: Stateful Packet Processing in Hardware
摘要: 尽管可编程NIC可以提供更好的可扩展性以处理不断增长的网络工作量,但为硬件中的有状态网络功能编程提供表达能力却又简单的抽象仍然是一项研究挑战. 我们使用FlowBlaze解决了这个问题,Flo ...
- Spring Boot教程(三十二)多数据源配置与使用(1)
之前在介绍使用JdbcTemplate和Spring-data-jpa时,都使用了单数据源.在单数据源的情况下,Spring Boot的配置非常简单,只需要在application.propertie ...
- Socket编程-基础使用
最后更新:2019-10-25 一 基本概念 socket, 又称为"套接字"或者"插座". 是操作系统提供的一种进程间通信机制.目前大多用于不同网络设备之间的 ...
- Oracle用函数或PIVOT实现行转列
原数据: 目标数据: 实现代码: SELECT YEAR AS "年", SUM (DECODE (QUATER, 1, RATE, 0)) AS "季度一", ...
- php mysql替换数据库中出现过的所有域名实现办法 (原)
2019-10-12备注: 数据量稍微有些大且前期数据库建设相当完善的可以看一下这边的方法,数据量小或者数据库建设不完善的可以参考这篇文章,前两天看的,没自己试,有需要可以试试 https://ww ...
- 大哥带的JavaScript伪协议
将javascript代码添加到客户端的方法是把它放置在伪协议说明符javascript:后的URL中.这个特殊的协议类型声明了URL的主体是任意的javascript代码,它由javascript的 ...
- Java多线程深度探索
线程 1.优先级 每个线程有一个优先级,更高优先级的线程优先运行,优先的意思是只是在分配cpu时间段的时候,得到的概率高一些.当在某个线程创建一个新的线程,这个线程有与创建线程相同的优先级.setPr ...
- beta week 1/2 Scrum立会报告+燃尽图 03
本次作业要求参见:edu.cnblogs.com/campus/nenu/2019fall/homework/9913 一.小组情况组长:贺敬文组员:彭思雨 王志文 位军营 徐丽君队名:胜利点 二.S ...