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 相关文章推荐
jQuery ui 利用 datepicker插件实现开始日期(minDate)和结束日期(maxDate)
May 22 Javascript
javascript实现textarea中tab键的缩排处理方法
Jun 26 Javascript
jQuery中delegate()方法的用法详解
Oct 13 Javascript
vue插件tab选项卡使用小结
Oct 27 Javascript
JS ES6中setTimeout函数的执行上下文示例
Apr 27 Javascript
vue.js组件之间传递数据的方法
Jul 10 Javascript
[原创]jQuery实现合并/追加数组并去除重复项的方法
Apr 11 jQuery
vuedraggable+element ui实现页面控件拖拽排序效果
Jul 29 Javascript
微信小程序分享海报生成的实现方法
Dec 10 Javascript
vue中axios请求的封装实例代码
Mar 23 Javascript
微信小程序实现点击生成随机验证码
Sep 09 Javascript
关于vue 项目中浏览器跨域的配置问题
Nov 10 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
PHP新手上路(十四)
2006/10/09 PHP
PHP使用ob_start生成html页面的方法
2014/11/07 PHP
谈谈 PHP7新增功能
2015/12/16 PHP
PHP内置加密函数详解
2016/11/20 PHP
thinkPHP简单实现多个子查询语句的方法
2016/12/05 PHP
Javascript & DHTML 实例编程(教程)DOM基础和基本API
2007/06/02 Javascript
List the UTC Time on a Computer
2007/06/11 Javascript
js 解决“options为空或不是对象”
2008/12/22 Javascript
Mootools 1.2教程 选项卡效果(Tabs)
2009/09/15 Javascript
初学Jquery插件制作 在SageCRM的查询屏幕隐藏部分行的功能
2011/12/26 Javascript
jQuery中阻止冒泡事件的方法介绍
2014/04/12 Javascript
JavaScript设置表单上传时文件个数的方法
2015/08/11 Javascript
最全面的百度地图JavaScript离线版开发
2016/09/10 Javascript
jQuery实现移动端手机商城购物车功能
2016/09/24 Javascript
微信小程序 label 组件详解及简单实例
2017/01/10 Javascript
老生常谈jquery id选择器和class选择器的区别
2017/02/12 Javascript
nodejs利用ajax实现网页无刷新上传图片实例代码
2017/06/06 NodeJs
JS实现简单的浮动碰撞效果示例
2017/12/28 Javascript
vue-cli中的babel配置文件.babelrc实例详解
2018/02/22 Javascript
Vue 无限滚动加载指令实现方法
2019/05/28 Javascript
Python中的time模块与datetime模块用法总结
2016/06/30 Python
通过python+selenium3实现浏览器刷简书文章阅读量
2017/12/26 Python
python3调用百度翻译API实现实时翻译
2018/08/16 Python
基于python使用tibco ems代码实例
2019/12/20 Python
pycharm无法导入本地模块的解决方式
2020/02/12 Python
python 监控logcat关键字功能
2020/09/04 Python
Scrapy中如何向Spider传入参数的方法实现
2020/09/28 Python
新加坡时尚网上购物:Zalora新加坡
2016/07/26 全球购物
匡威爱尔兰官网:Converse爱尔兰
2019/06/09 全球购物
医药大学生求职简历的自我评价
2013/10/17 职场文书
如何做好总经理助理
2013/11/12 职场文书
数学专业推荐信范文
2013/11/21 职场文书
日语专业个人的求职信
2013/12/03 职场文书
个人对照检查材料思想汇报(四风问题)
2014/09/25 职场文书
文员岗位职责范本
2015/04/16 职场文书
2016年中学植树节活动总结
2016/03/16 职场文书