React 组件渲染和更新的实现代码示例


Posted in Javascript onFebruary 21, 2019

最近一直写React,慢慢就对里面的一些实现很好奇。最好奇的就是自定义标签的实现和this.setState的实现。这里不分析JSX是如何解析的,所有组件都用ES5方式编写。

组件渲染

渲染时候,我们会调用render方法。类似下面这样:

var SayHi = React.createClass({
 getInitialState: function() {
  return {verb: 'say:'};
 },
 componentWillMount: function() {
  console.log('I will mount');
 },
 componentDidMount: function() {
  console.log('I have mounted');
 },
 render: function() {
  return React.createElement("div", null,this.state.verb, "Hello ", this.props.name);
 }
});

React.render(React.createElement(SayHi, {name: "Cynthia"}), document.getElementById("container"));

结果:

页面打印:
say: Hello Cynthia
控制台打印:
I will mount
I have mounted

React 组件渲染和更新的实现代码示例

这是我画的React对象上的一些属性和方法。

当调用render方法时,render会去调用一个map方法,根据传入参数的不同,把被render的对象分为以下三类:
* 文本
* 原生
* 自定义标签

文本

对于文本,React会实例化一个文本节点的对象,并且调用该对象的mount方法。在这个mount方法中,把文本放到一个span中,调用容器组件的innerHTML,进行渲染。

原生标签

对于原生标签,React会实例化一个处理原生标签的对象,并且调用该对象的mount方法。在这个mount方法中,拼接一个字符串,并且不断递归上面的map方法,最后把拼接好的字符串放到容器组件的innerHTML中,进行渲染。

自定义标签

这个应该是大家最好奇的。自定义标签虽然叫标签,其实就是一个类。实例化一个处理自定义标签的对象后,首先React会处理自定义标签的生命周期方法,然后再次递归调用子组件的render方法进而调用map方法,直至把自定义标签分解为前两种标签。

更新

首先,我们统一一下认识。在React里调用this.setState()会使得组件更新,调用this.state = {}只会更改本组件的状态,但是不会使得组件更新。

如果我要更新一个组件,我会这样写。

var SayHi = React.createClass({
 getInitialState: function() {
  return {verb: 'say:'};
 },
 componentWillMount: function() {
  console.log('I will mount');
 },
 componentDidMount: function() {
  console.log('I have mounted');
 },
 changeVerb: function(){
  this.setState({verb: 'write:'});
 }
 render: function() {
  return React.createElement("div", this.changeVerb.bind(this),this.state.verb, "Hello ", this.props.name);
 }
});

React.render(React.createElement(SayHi, {name: "Cynthia"}), document.getElementById("container"));

执行结果:

页面打印:
say: Hello Cynthia
点击文本,页面内容更新成:
write: Hello Cynthia

与更新相关的属性和方法如下:

React 组件渲染和更新的实现代码示例

在调用this.setState()以后,也是调用了一个map方法,根据传入参数不同,依然把要更新的标签分为文本、原生标签、自定义标签三类。具体处理过程如下。

文本

文本节点处理很简单,判断要更新后的文本与当前文本是否===,不是全等就删除原来文本,插入新文本。

自定义标签

对于自定义标签,首先根据对象的引用、key是否相同,判断是否需要更新。如果需要更新,就继续调用上述map方法进行子组件的更新。又是一个递归。但是注意,这里的map方法和渲染部分的map方法不是一个方法哟。

原生标签

对于原生标签,首先更新组件的属性,然后update子树,用diff算法来比较新的子树与目前标签的子树的不同,形成一个差异树,然后用patch方法,把这个差异树更新到真正的DOM树上。

总结

很复杂的过程,让我用流水账写了一遍。没能道出其中精华。以后继续探索,写的详细一些。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 组件之旅(一)分析和设计
Oct 28 Javascript
js中有关IE版本检测
Jan 04 Javascript
jQuery向后台传入json格式数据的方法
Feb 13 Javascript
ECMAScript6函数剩余参数(Rest Parameters)
Jun 12 Javascript
JS脚本实现动态给标签控件添加事件的方法
Jun 02 Javascript
jQuery实现的兼容性浮动层示例
Aug 02 Javascript
js仿京东轮播效果 选项卡套选项卡使用
Jan 12 Javascript
Javascript下拉刷新的简单实现
Feb 14 Javascript
使用Node.js搭建静态资源服务详细教程
Aug 02 Javascript
基于Axios 常用的请求方法别名(详解)
Mar 13 Javascript
微信小程序 scroll-view 实现锚点跳转功能
Dec 12 Javascript
vscode中Vue别名路径提示的实现
Jul 31 Javascript
vue图片上传本地预览组件使用详解
Feb 20 #Javascript
Vue 后台管理类项目兼容IE9+的方法示例
Feb 20 #Javascript
浅谈小程序 setData学问多
Feb 20 #Javascript
9102年webpack4搭建vue项目的方法步骤
Feb 20 #Javascript
微信小程序五子棋游戏AI实现方法【附demo源码下载】
Feb 20 #Javascript
解决element ui select下拉框不回显数据问题的解决
Feb 20 #Javascript
微信小程序五子棋游戏的悔棋实现方法【附demo源码下载】
Feb 20 #Javascript
You might like
codeigniter框架批量插入数据
2014/01/09 PHP
php 发送带附件邮件示例
2014/01/23 PHP
php中将一个对象保存到Session中的方法
2015/03/13 PHP
基于JQuery的一个简单的鼠标跟随提示效果
2010/09/23 Javascript
JavaScript通过RegExp实现客户端验证处理程序
2013/05/07 Javascript
js单向链表的具体实现实例
2013/06/21 Javascript
对于this和$(this)的个人理解
2013/09/08 Javascript
javascript中局部变量和全局变量的区别详解
2015/02/27 Javascript
JavaScript中调用函数的4种方式代码实例
2015/07/08 Javascript
JavaScript中循环遍历Array与Map的方法小结
2016/03/12 Javascript
基于jquery实现轮播焦点图插件
2016/03/31 Javascript
AngularJS中的包含详细介绍及实现示例
2016/07/28 Javascript
Vue监听页面刷新和关闭功能
2019/06/20 Javascript
对Layer UI 模块化的用法详解
2019/09/26 Javascript
taro 实现购物车逻辑的实例代码
2020/06/05 Javascript
vue实现移动端返回顶部
2020/10/12 Javascript
[08:44]DOTA2发布会群星聚首 我们都是刀塔人
2014/03/21 DOTA
[01:45]IMBATV TI4前线报道-选手到达
2014/07/07 DOTA
Python将多个excel表格合并为一个表格
2021/02/22 Python
Sublime开发python程序的示例代码
2018/01/24 Python
Flask框架各种常见装饰器示例
2018/07/17 Python
Python求离散序列导数的示例
2019/07/10 Python
Python3以GitHub为例来实现模拟登录和爬取的实例讲解
2020/07/30 Python
基于python的opencv图像处理实现对斑马线的检测示例
2020/11/29 Python
用HTML5实现手机摇一摇的功能的教程
2012/10/30 HTML / CSS
世界领先的高品质定制产品平台:Zazzle
2017/07/23 全球购物
Tomcat Mysql datasource数据源配置
2015/12/28 面试题
SQL面试题
2013/04/30 面试题
八年级英语教学反思
2014/01/09 职场文书
爱祖国演讲稿
2014/05/04 职场文书
夏季药店促销方案
2014/08/22 职场文书
个人委托书怎么写
2014/09/17 职场文书
税务干部群众路线教育实践活动自我剖析材料
2014/09/21 职场文书
晋江市委常委班子四风问题整改工作方案
2014/10/26 职场文书
普通党员个人整改措施
2014/10/27 职场文书
一些让Python代码简洁的实用技巧总结
2021/08/23 Python