React/React Native框架的设计思想

来源:互联网 发布:微信交友公众号源码 编辑:程序博客网 时间:2024/05/22 08:15
  1. React Native框架的编程思想


(一)React Native框架的设计思想
    1. 基于响应式编程范式
      从其全局刷新的机制以及flux架构可以得出,react native是基于响应式编程范式的产物,所以其只关注数据流和消息的传递方式来进行编程。

    2. 使用JSX直观地定义用户界面(语法糖、模板引擎、avalon)
      facebook认为减少心智的负担比文件分离更为有用,所以facebook讲xml+js组合成JSX语言,从而让这种语言可以完成css、html、js的所需要描述的所有逻辑。本质上JSX只是一种语法糖,最后通过编程都会将其编译成js脚本进行使用,而这种使用xml来描述界面结构的方式与模板是十分相似的,但其本质还是JSX语法和编译后的js。这样做的好处是通过直观的方法来呈现界面的结构,能方便开发组织样式和事件等逻辑。二避免了传统的方式去构建重复的界面,如列表、表格,能用简洁的语法来表示复杂的界面(这一点与avalon十分类似)。

    3. 简化的组件模型,组件即是状态机(props、state、生命周期、组件嵌套)
      组件并不是一个新的概念,它意味着某个独立功能或界面的封装,达到服用或者业务分离的目的。但在react中,组件虽然也是对独立功能也界面的封装,但更将其看作状态机。组件的某种状态就对应某种界面,所以当组件发生更新或者子组件发生替换等事件,react就会去以最高效的方式去比较两个界面并更新dom或ui。
      正是因为组件的本质就是一个状态机,所以组件内部通常有两种属性,props&state,props可以作为内部常量或者外部的输入参数,而state是内部的状态变量,所以可以看出组件是相当独立的,使用组件像使用函数一样简单,这样的设计给通过组件的嵌套来构建复杂见面变得简单而高效,如下图:  通过简单的嵌套即可快速实现复杂的图像界面。


      组件的生命周期函数:


    4. immutability让数据模型更简单
      react提倡只使用只读数据来建立模型,如果要修改,只能产生一份包含新的修改的数据,如下

      只读数据可以让代码更加安全和容易维护,让你不必担心数据在某个角落被某段神奇的代码修改,也不必为了找到要修改的地方而苦苦调试。结果react,只读数据可以让react组件仅仅通过比较引用是否相等即可决定是否重新render,这在复杂的界面上极大地提高了性能。

    5. 界面刷新机制(一次性整体刷新、虚拟dom、高效的diff算法)
      以往,我们都基于数据模型驱动UI的形势来实现功能,但在具体的实现却会困难重重,因为各方的调用与依赖关系十分复杂,容易导致项目代码难以维护(详见说明1)。然后facebook为了简化这个过程,采用了另外的思路,就是通过定义事件周期(event loop)在事件周期内修改虚拟dom,然后在一个事件周期的结束进行dom diff分析出最小的更新操作后,再同步到UI或者dom上,也就是每次都全局刷新一遍。

      全局刷新带来的好处:
      将所有的更新ui的业务逻辑代码全部移入框架内部,开发者只需要关系数据流的绑定即可,这样让业务逻辑,因为当我们面对不断变化的UI界面时,仅仅需要考虑UI的构成即可。(面向数据流与信号传递编程,响应式编程思想)

      全局刷新的性能疑问:
      由于全局刷新是需要配合event loop事件周期的,所以操作虚拟dom(内存)的效率比操作dom的效率要高不少,所以性能反而会提供。但对于iOS来说,iOS本来就是以60fps的周期来同步界面的操作然后进行渲染的,所以这点上也不影响iOS的性能。

      React中最神奇的部分莫过于虚拟DOM,以及其高效的Diff算法。这让我们可以无需担心性能问题而”毫无顾忌”的随时“刷新”整个页面,由虚拟DOM来确保只对界面上真正变化的部分进行实际的DOM操作。React在这一部分已经做到足够透明,在实际开发中我们基本无需关心虚拟DOM是如何运作的,所以下面介绍一下diff dom算法。

      diff dom算法规则:
      diff dom结合了web界面提供了两个简单的假设:(1)两个相同组件产生类似的dom结构,不同的组件产生不同的dom结构(2)对于同一层次的一组子节点,它们可以通过唯一的id进行区分。
      所以整个算法规则如下
      *逐层进行节点比较:直接以层级横向行进比较,若一旦有不同,则无需比节点的子节点了。
      *不同节点类型的比较:节点类型变了,就直接判断了修改了,直接更新,后面的节点类型无需比较。
      *相同节点类型,不同属性的比较:属性不同,则进行属性重设。
      *列表节点的比较:没提供key按照默认规则,提供了key可以更新属性的方式完成更新。

      note:
      说明1:对于移动节点的情况,在rn中其实并没有进行移动行为,而是直接将移动的目标删除,重新创建,然后添加到目标位置,更新属性来完成操作,如下图:



      note:
      说明1:数据模型驱动UI:即是数据模型的变化(网络请求or用户交互导致的更新)需要用户实现响应的业务逻辑实现UI的更新,若遇到一个数据模型的更新会影响多个部分的UI界面的情况下就得全局刷新,过多的全局刷新容易导致性能的下降。过于复杂的UI更新操作

    6. 单向的数据流动(flux、Redux、Fluxmm)
      在传统的mvc方案中,数据绑定是双向的,model可以更新view,view也可以更新model,并且model也可以更新model,因此容易出现连锁更新,在比较复杂的界面上开发的逻辑比较容易出现混乱而导致后期的不好维护。如下图:

      因此facebook提供flux的单向数据流来解决这个问题。

      Flux的简单架构图:

      Flux的详细架构图:

      其中主要模块的分工如下:
      *Action Creators(Action):Action的创建者,通过调用Dispatcher派遣具体的action消息。
      *Dispatcher:分发action、注册action的注册函数,通常就是调用Store完成数据、信息的更新。
      *Store:接受事件、更新公共信息,调用view的注册方法完成view update
      *ReactViews(View):构建界面状态机,交互,调用action creators产生action。
      自此,四个主要组件构成一个单向循环的事件流环,让代码更清晰。
                    

0 0