React

56 阅读4分钟

组件化

React的组件化思路算是对树型结构做了个很好的抽象,所以能有React-DOM, React Native, React Canvas这些各类的实现,只要是树型结构理论上都能在React及JSX上得到实现。这个通用性是非常强的,因为貌似目前还没见过非树型结构的UI实现方案(Canvas画布类型大概算是特例,但具体应用起来多少也都还是有树型的概念)。

React的组件有几个核心原则:

  • 单一功能:组件理想情况下只实现单一的功能,而且其参数由props传入、而传出则一般通过props内传入的方法进行调用传出。

  • 可复用:利用方式非常简单,即通过props传入到jsx的tag里即可。

  • 不可修改:至少目前官方没有给出明确的方法来进行React Class的继承或修改。从这点上来看,倒是很粗暴地达成了“对扩展开放、对修改关闭”的原则。虽然不能修改,但还是可以通过创建另一个类调用的方式进行包装或组合。

  • props与state:分别代表传入组件的参数与组件的内部状态

其中的思路主要在官方的BLOG里有描述:

深入理解 React

虚拟DOM

React整出虚拟DOM的由来是:传统DOM操作太慢了。其实传统的方式不见得慢,只是通常人们会用比较低效的方式去操作DOM,比如整个视图重新渲染等等。

在之前也有针对这点的优化,比如手动控制DOM更新的范围、数据绑定方式等等,都能减少DOM操作的开销,但这些方式要么与传统的HTML思路不同,要么需要每个程序员的代码优化,显然这是Facebook所不想要的,所以他们整了虚拟DOM,把这部分的优化放到了框架层。

React的解决方案是在JSX模板字符串上进行Diff操作来决定整棵树需要如何修改,虽然性能不错但显然其中复杂度非常高,于是导致了React庞大的代码体积。相对而言, Riot所采取的思路就简单得多:直接基于浏览器内的DOM进行diff,所以Riot只有React的1/8的代码体积。

难道React不注重前端框架体积么?我觉得不至于。但也许这也就是Facebook开脑洞的地方:有了这一套的虚拟DOM,他们就可以将React应用在所有其它的渲染体系上,比如React Native或React Canvas,这显然是Riot的思路所无法做到的,因为他太依赖DOM了。

单向数据流

这个在React里其实并不是必须使用的思路,只是比起传统的MVC框架,Facebook认为其中的Model状态在应用规模扩大了之后会使复杂度急剧上升,难以维护各类model之间的关系。所以,引入了Dispatcher的概念,使所有的对数据的交互都由Dispatcher进行,而视图的状态则统一地由Store传入,大致关系如下图。

这样结构的理想情况下:

  • 状态与数据:一个视图的状态与数据完全依赖于某个store的状态

  • 数据交互:而视图对数据的交互则去调用dispatcher中的接口

而具体的数据分发、请求、响应处理什么的,都在dispatcher与store的具体逻辑中,视图无须关注。

嗯,看起来瞒美好的,基本上完全把视图和数据隔离开来了,但另一方面而言总感觉代码变得有些不是特别直观(对比起传统的Model而言)。Dispatcher究竟对应了什么Store?不知道;相应的操作会对哪些视图有影响?不知道;具体Model有哪些方法?也不知道。在某些情况下,这也许就是这样结构的目标,但对于某些业务而言也许也又会带来很多复杂度,这就得看前端架构师的选择了。

总体而言,Facebook, Nice Try。至少我们有了个MVC之外的选项,可以使得View, Controller, Model都相对纯粹,不太需要太依赖于彼此。