Why React

无法用语言准确表达思维时,就用公式;一个不行,那就两个

—— 李老师

本文假设读者已了解react的基本概念,并有少量react开发实践。如果没有,请先阅读
http://www.ruanyifeng.com/blog/2015/03/react.html

当前我们如何开发业务?

react1

备注:微信不支持公式,所以我这边截图。
补充一下f表示一次用m生成v的渲染方法
g是界面发生交互时,对m做修改的方法

当前业务模块之间如何通信?

  1. 回调模式:callback
  2. 观察者模式:on / fire (addEventListener / removeEventListener)
  3. 伪总线模式:fcContextChange

三种模式没有本质区别:

  1. 回调模式,一次创建一条通信链路,此链路工作时不与其他链路发生干扰。
    react2
  2. 观察者模式,一次创建多条通信链路,每条链路工作时与其他链路发生干扰。
    react3
  3. 伪总线模式,是一种特殊的观察者模式,信息的发出者是一个固定的模块。

在目前系统中,只存在兄弟通信和父子通信,不存在跨树通信,即孩子不能跟叔叔直接通信。如果要跟叔叔通信,必须借助祖先中转。

现在开始简化模型:

a. 假设系统中模块之间的链路能双向通信,这样可以将有向链路换成无向链路;
b. 假设任意两个模块之间都可以存在链路,但只允许存在一条链路,这样之前不同的链路类型下降成单条链路的一个参数,并且将祖先中转缩短成直接通信;
c. 把系统中的模块看作顶点,模块间通信链路看作边,则系统变成了无向图。
react4

这是模型简化后的链路数量,而目前我们系统中的链路数比这多得多,因为我们允许节点间有多条链路,而且链路是单向通信的。

我们开发业务时很大一部分工作量就是创建各种通信链路,随着系统复杂性不断增加,图越来越复杂,代码逻辑就没人能看懂了,因为数据在系统中的流动是没有规律的。

React基本原则2:在React中,数据流是单向的。数据总是自顶而下流动,内部不允许出现反向数据流。React简化通信的方法相当粗暴,既然管理不好通信,那么干脆禁止通信。

如何用React满足我们的通信需求?React的做法是:
a. 把整个应用抽象成一个数据集;
b. 每个子模块使用数据集的一部分做渲染,涉及渲染的数据通过props向下传递;
c. 每个子模块都可以直接修改最顶层的数据集。

现在,系统中通信链路条数变成了n,系统复杂度完全在我们掌控之中。当然这样做也是有弊端的,所有数据放在一个model中,这个model必然很庞大,维护起来需要一定技巧,相应地出现了flux和redux等框架专门用于管理model,目前我们没有引入,准备使用ER.model,加强命名规范,来临时解决这一问题。

react5

最关键,上图绿色链路的创建过程是半自动化的,只需要把修改model的回调函数mode.dispatch通过props一层层传递下去。当然,绿色链路的创建可以利用react.context做成全自动,但react官方对context的使用有疑虑,并且API在将来可能会修改,所以暂时没有引入。

Note

Context is an advanced and experimental feature. The API is likely to change in future releases.

Most applications will never need to use context. Especially if you are just getting started with React, you likely do not want to use context. Using context will make your code harder to understand because it makes the data flow less clear. It is similar to using global variables to pass state through your application.

If you have to use context, use it sparingly.

Regardless of whether you’re building an application or a library, try to isolate your use of context to a small area and avoid using the context API directly when possible so that it’s easier to upgrade when the API changes.

当前我们如何测试ui和业务模块?

答案是测试基本靠手。怎么测试交互?目前有基于web driver的OneUX SDK方案。这个方案用脚本模仿了鼠标键盘操作,允许我们实现自动化测试。
但问题不在这里,而是工作量的问题。模拟操作的方式,归根到底是QA把手动测试过程用脚本记录下来。如果测试一次性通过,手动测试和写脚本的工作量是一致的。

react7

在React中,自动化测试变得非常简单。还记得React基本原则1么?props + state是渲染界面view的唯一依据。因此,用户在页面的交互行为,最终都转化成props或state的变化。

react8

react9