为了账号安全,请及时绑定邮箱和手机立即绑定

React诞生的历史原因

标签:
JavaScript
React诞生的原因

React是Facebook开发的一款的JS库,那么Facebook为什么要创造React?
Facebook认为MVC无法满足他们的扩展需求,由于他们非常巨大的代码库和庞大的组织,使得MVC很快变得复杂,每当需要添加一项新功能或者特性时,系统的复杂就成级数的增长,致使代码变得脆弱而不可预测,结果导致他们的MVC正在土崩瓦解。认为MVC不适合大规模的应用。当系统中有很多模型和相应的视图时,其复杂度就会迅速扩大,非常难以理解和调试,特别是模型和视图可能存在双向数据流动。

解决这个问题需要“以某种方式组织代码,使其更加可预测”,这通过Flux和React已经完成

Flux是一个系统架构,用于推进应用中的数据单向流动。React是一个JavaScript框架,用于构建“可预期的”和声明式的”Web用户界面”,它已经使Facebook更快地开发Web应用。

主要来讨论React方面的问题:
React用来解决什么问题,官方网站上这样说道:

We build React to solve one problem:building large applications with data that changes over time.

构建数据会随着时间改变的大型应用,React主要有以下特点:

1.简单的表述任意时间点应用应该呈现的样子,React就会自动管理UI界面更新当数据发生变化的时候
   2.在数据发生改变时,React实际上仅仅更新了变化的一部分而已
   React是关于构造可重用组件的,实际上,使用React时,我们做的更多的是构建组件。通过封装,使得代码复用,测试以及关注点分离更加容易。

从React官方网站上,通过《Why did we build React?》了解到创建React文档的四个原因:
1.React不是一个MVC框架,React是一个构造可组合式用户界面的库。它鼓励创建可重用的UI组件会随着时间而改变的数据。
2.React不使用模板
传统上,web应用UIs使用模板或者html指令构造。这些模板规定一套完整的抽象使你可以去构建你的UI
不同的是,React处理构建用户界面通过将他们分解为组件。这意味着,React使用一个真正的,全功能的编程语言去渲染视图。
3.响应式更新非常简单
在一个传统的JS应用中,需要考虑数据变化然后指示DOM做出变化,使其保持最新的。甚至AngularJS,提供一个声明式接口经由指令和数据绑定请求一个关联的函数去手动更新DOM节点。
React采用不同的方法,当组件第一次初始化时,render方法调用,为试图生成一个轻量级的表现。通过这个表现,产生一个标签字符串,然后插入文档中。当数据变化时,render方法再次被调用。为了尽可能有效的完成更新,我们比较值钱调用的render返回的值与新的值,然后产生一个最小的变更去应用DOM中。

render返回的数据既不是一个字符串也不是一个DOM结点。它是一个轻量级的类型,描述DOM应该是什么样子的。

4.HTML5仅仅是个开始
因为React有自己轻量级的文档表现,我们可以用它做一些很酷的事情
1.Facebook动态表格可以通过渲染取代HTML.
2.Instagram是一个’single page’网页应用完全由React和Backbone.Router构建的。设计者可以像通常一样使用JSX编写React代码。
3.我构建内部的应用雏形运行React在一个web工作站上,使用React去驱动本地ios视图通过一个Objective-C桥。
4.你可以运行React在服务器上,便于SEO、性能、代码分享和项目灵活性。
5.事件在全部现代浏览器(包括IE8)下表现一致性还有符合标准化,并且自动使用事件委派。

React的主要原理

Virtual DOM和虚拟DOM
传统的web应用中,操作DOM一般是直接更新操作的,但是我们知道DOM更新通常是比较昂贵的。而React为了尽可能减少对DOM的操作,提供了一种不同而有强大的方式来更新DOM,代替DOM直接操作。就是Virtual DOM,一个轻量级的虚拟DOM,就是React抽象出来的一个对象,描述DOM应该是什么样子,应该如何呈现。通过 这个Virtual DOM去更新更真实的DOM,而这个Virtual DOM管理真实的DOM更新。
为什么通过这多一层的Virtual DOM操作就能更快呢? 这是因为React有个diff算法,更新Virtual DOM并不保证马上影响真实的DOM,React会等到事件循环结束,然后利用这个diff算法,通过当前新的dom表述与之前的作比较,计算出最小的步骤更新真实的DOM。

React Diff

1.虚拟的DOM确保只对界面上真正发生变化的部分进行实际的DOM操作。
Web页面是由DOM树来构成的,当其中的某一部分发生变化时,其实就对应某个DOM节点发生了变化。在React中,构建UI界面的思路是由当前状态决定界面。前后两个状态对应两个界面,然后由react来比较两个界面的区别。
Facebook的工程师,他们对于web界面做了两个简单的假设,使得Diff算法复杂程度直接降到了O(n)
1.两个相同组件产生类似的的DOM结构,不同组件产生不同的DOM结构
2.对于同层次的一组子节点,他们可以通过唯一的id进行区分

在节点的同一位置前后输出了不同类型的节点,React直接删除前面的节点,然后创建并插入新的节点,删除节点就会彻底销毁该节点,如果该删除的节点下有子节点,那么这些子节点也会被完全删除,它们也不会被用户后面的比较

当React在同一个位置遇到不同的组件时,也是简单的销毁第一个组件,而把新创建的组件加上去。不同的组件一般会产生不一样的DOM结构,与其浪费时间去比较它们的结构,他们的结构基本上是不会等价的,还不如完全创建一个新的组件上去。

2.逐层次进行节点比较
在React中,树的算法很简单,两棵树只会对同层次的节点进行比较。把之前的树和修改之后的树进行节点同层次的比较,React对同一个父节点下所有的子节点进行比较。当发现节点已经不存在了,就会把这个节点和它的子节点完善删除掉,不会进行进一步的人比较,所以这样只要遍历一次树,就可以完成对DOM结构的比较。

React只会考虑同层节点位置的变换,对于不同层的节点,只有简单的删除和创建。当根节点发现子节点中的A不见了就会直接销毁A;而当D发现自己多了一个子节点,就会创建A作为子节点。

为了保持稳定的结构会有助于性能的提升,我们可以通过CSS隐藏或显示某个节点,而不是真正的移除或者添加DOM节点。

相同类型的节点,算法比较简单,React会对其属性进行重设而实现节点转换。
比如:
renderA:


renderB:


虚拟DOM的style属性稍微不同,其值并不是一个简单的字符串而必须是一个对象。


3.列表节点的比较:
React对于不在同一层的节点比较,即使它们完全相同,也会销毁并重新创建,当它们在同一层的时候就要用到列表节点的Diff算法,这里写图片描述


如果不设置这个li 的key值,会造成列表在更新时候的性能问题。React不能很高效的去更新这个列表

Components 组件

在DOM树上的节点被称为元素,在这里则不同,Virtual DOM上称为commponent。Virtual DOM的节点就是一个完整抽象的组件,它是由commponents组成。

component 的使用在 React 里极为重要, 因为 components 的存在让计算 DOM diff 更高效。

原文出处

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消