学习使我快乐《一》--重拾一年前的react
2017-11-03 14:47
218 查看
以前在实习的公司的时候,对Vue,Angular,和React进行过研究,使用vue1.x,2.x开发过几个项目,毕业设计采用了Angular2.x,如今公司任然使用Angular1.x。对于开发小型的项目而言,我只能说vue上手特别快。他俩可是吵得不可开交,使用起来也特别像,因为同时有vue和angular的项目,好几次我都不经意间错误的把v-model写成ng-model或则ng-model写成v-model.
我想学React,因为前两个哥们实在是像,而且我喜新厌旧,更重要的是,初识的React虚拟DOM给我留下了比较特别的印象,里面的element diff中采用顺序优化手段也让我记忆尤新,如今我想重拾前端技术,所以决定正式入坑React。愿最终使用react等前端技术,实现一个属于自己的网站。
浏览器创建DOM树,根据解析的HTML创建,Virtual DOM树也可以根据自己的模板语言JSX创建相应的节点,但他们编译的时候都是通过对一些类的调用,创建了相应的DOM节点,然后在将这些节点连接到一棵已有的树上。
DOM树的创建源码可以参照《从Chrome源码看浏览器如何构建DOM树》
而对React中的Virtual DOM节点,是通过一个createElement函数创建的,每个Virtual DOM的节点是一个ReactELement类的对象。
如下是React对JSX的内部处理(JSX->JS)
上面的输出结果分别是0,0,2,3。
首先,事务是将需要执行的方法使用wrapper封装起来,wrapper的意思就是像洋葱一样一层一层的包裹,每个事务是一层。这里出现了两个事务,一个是处于最外层的事务A,一个是通过setTimeout创建的事务B。直接在componentDidMount中的setState是在事务A中,另外两个则处于事务B中。
而内部处理,事务A的中的setState中数据会放在一个脏数据队列中,等待更新,也就是说处于A中的两个setState只是将他们放在了队列,并没有对他们的值进行更新操作,所以会输出0,0。而处于事务B中的setState并不会将state放入脏数据队列中,而是直接执行。执行之前有一个脏数据更新操作,也就是会先将处于脏数据队列中的数据 进行更新后再开始执行事务B中的数据,执行事务B时val的值为1,故顺序执行并更新数据,使得事务B中的输出数据为2,3。
更多详情可以参考《深入React技术栈》
可以参看以前的一篇博客《React从使用到源码学习》
更多详情可以参考《深入React技术栈》
我想学React,因为前两个哥们实在是像,而且我喜新厌旧,更重要的是,初识的React虚拟DOM给我留下了比较特别的印象,里面的element diff中采用顺序优化手段也让我记忆尤新,如今我想重拾前端技术,所以决定正式入坑React。愿最终使用react等前端技术,实现一个属于自己的网站。
Virtual DOM 节点创建
首先,我们都知道React并不直接对DOM树进行操作,对DOM的操作都是通过与Virtual DOM比较,然后在进行相应的重排和渲染的,学习React,我们就要学习这棵Virtual DOM树。浏览器创建DOM树,根据解析的HTML创建,Virtual DOM树也可以根据自己的模板语言JSX创建相应的节点,但他们编译的时候都是通过对一些类的调用,创建了相应的DOM节点,然后在将这些节点连接到一棵已有的树上。
DOM树的创建源码可以参照《从Chrome源码看浏览器如何构建DOM树》
而对React中的Virtual DOM节点,是通过一个createElement函数创建的,每个Virtual DOM的节点是一个ReactELement类的对象。
如下是React对JSX的内部处理(JSX->JS)
//JSX const app=<Nav color="bule"><Profile>click</profile></Nav>;
//JS const app=React.createElement( Nav, {color:"blue"}, React.createElement(Profile,null,"click") );
有趣的setState机制
先看一下下面这段代码,如果你能准确判断输出,那你或许就理解了setState的的调用栈和对事务有基本的认识。import React,{component} form 'react'; class Example entends Component{ constructor(){ super(); this.state={ val:0 } }; componentDidMount(){ this.setState({val:this.val++}; console.log(this.val); this.setState({val:this.val++}; console.log(this.val); setTimeout(()=>{ this.setState({val:this.val++}; console.log(this.val); this.setState({val:this.val++}; console.log(this.val); },0); } render(){ return null; } }
上面的输出结果分别是0,0,2,3。
首先,事务是将需要执行的方法使用wrapper封装起来,wrapper的意思就是像洋葱一样一层一层的包裹,每个事务是一层。这里出现了两个事务,一个是处于最外层的事务A,一个是通过setTimeout创建的事务B。直接在componentDidMount中的setState是在事务A中,另外两个则处于事务B中。
而内部处理,事务A的中的setState中数据会放在一个脏数据队列中,等待更新,也就是说处于A中的两个setState只是将他们放在了队列,并没有对他们的值进行更新操作,所以会输出0,0。而处于事务B中的setState并不会将state放入脏数据队列中,而是直接执行。执行之前有一个脏数据更新操作,也就是会先将处于脏数据队列中的数据 进行更新后再开始执行事务B中的数据,执行事务B时val的值为1,故顺序执行并更新数据,使得事务B中的输出数据为2,3。
更多详情可以参考《深入React技术栈》
diff算法
所谓diff算法,就是采取一系列的优化措施,将DOM树转化成和和virtual DOM结构一样的树,使得开销降低到O(n)。可以参看以前的一篇博客《React从使用到源码学习》
更多详情可以参考《深入React技术栈》
相关文章推荐
- 学习使我快乐《二》--搭建自己的React脚手架
- React的学习
- React学习笔记(九)列表
- React的学习(下)
- react native 学习笔记之hello world
- React-Native学习指南
- React-Router 学习笔记
- react学习--2
- react native 学习笔记----网络
- react native 学习笔记之指定样式,宽,高
- React学习之扩展浅比较(三十四)
- React学习之扩展LinkedStateMixin双向绑定(三十五)
- React学习之进阶上下文(十九)
- linux学习八大技巧 枯燥中体味别样快乐
- ReactNative 学习笔记 Code Push 热更新
- ReactNative学习之:开发之图标库react-native-vector-icons
- ReactNative学习十四-再次弹性盒(Flexbox)
- React-Native学习之 防止键盘遮挡TextInput
- React学习笔记3