4

这篇文章是我在迁移之前写的, 现在简聊(http://talk.ai)已经完全切换到 React.
公司技术内容更新会贴在: http://weibo.com/teabot


原理

我觉得 React 是我目前接触到的开发 Web 应用最好的一个方案.
我刚用熟 Backbone 时候在想模板引擎的作用, 怎样把数据转化成为界面,
在数据给定的情况下, 界面是完全遵照数据改变的..
这个有点像数学里, 自变量因变量, 中间就被一个函数关联了,
更重要的, 其实数据我们应该只存储一份, 因变量根据函数计算出来就好了

回到应用上来, 数据定义好后, 界面就完全是根据数据渲染了
在 Backbone 中, 我们需要频繁操作 DOM 来保证界面到达最新状态,
甚至有时候, 因为 DOM 上保存的状态和数据不同步, 导致 Model 计算出错
这一切, 让我不断觉得写应用时就不应该存在 DOM 操作

出于这些想法, 我开始学习了 Ractive, 然后是 Vue, 现在是 React.
React 的基本思路就是, 数据更新之后, 渲染完整的界面的状态,
而 DOM 则根据新的状态, 从原来的基础上, 做最小的操作, 来保证性能和状态

关于底层的细节, 代码我没看懂代码, 搜索到的资料上对于这部分有描述:

React’s diff algorithm
http://calendar.perfplanet.com/2013/diff/

摘录一些有意思的地方:

  • 为了简化 DOM 算法复杂度, DOM 的 Diff 限制在层级一样的节点
  • 列表渲染的节点, 需要提供 key 属性来区分出唯一性
  • 对比到 Component 时, 整个 Component 不同直接替换, 不按 DOM 比较
  • React 的事件代理是自己实现的(和 jQuery 有区别, 我写应用遇到过)
  • setState 方法可以将 DOM 标记需要重新渲染. 细化这个操作可以提升性能
  • 可以定制 Component 的 shouldComponentUpdate 方法自行判断是否渲染, 提升性能

用户

主要是 Facebook 在生产环境使用了 React, 因此给人感觉是挺靠谱的

How is Facebook's React JavaScript library?
http://www.quora.com/React-JS-Library/How-is-Facebooks-React-JavaScrip...

Using React to speed up the Khan Academy question editor
http://benalpert.com/2013/06/09/using-react-to-speed-up-khan-academy.h...

Who is using Facebook React?
http://www.quora.com/React-JS-Library/Who-is-using-Facebook-React

搭配 CoffeeScript

我用 React 写了两个小应用, 感觉 React 思路非常清晰,
对我来说比较重要有一点是语法支持, 原生的 JSX 语法其实非常不方便编辑.
但是在 CoffeeScript 里, 语法就是非常简单的缩进, 比 HTML 清晰多了.

另一个有意思的 Component 的概念, 类似 Backbone 的 View, 但轻量多了
而且, 因为 React 使用数据表达的 DOM, 写起来非常简化,
以及其组合的方式, 结果是 Component 的划分也非常明确和细化,
可以看我的应用里为了组合 Component 怎样划分的:

https://github.com/jiyinyiyong/react-todolist/tree/master/coffee/view

还有一个是, 因为界面是根据 Model 自动渲染的, 而操作 Model 其实很简单,
于是我们就有大量的精力可以腾出来对付 Model 以及 ViewModel 类似的概念,
得益于此, 我用 React 轻松完成了 infinite scrolling 的效果, 完全不用写 DOM 操作:

https://github.com/jiyinyiyong/osx-fonts-view/blob/master/coffee/main....

中型(大型?)项目关心的

我的个人项目不用 Backbone, 因为太臃肿了, 但是对公司的中型项目来说还算合适,
由于我对于 React 的认同, 特别是 Facebook 用在生产环境, 所以完成关心大应用的场景

  • 性能

据说很高, 因为消耗的不是 DOM 操作的性能, 而是 JS 性能, JS 本身其实挺快的
我没找到个靠谱的测试, 可以补上..

  • 复杂的 View

我实践过的例子比较简单, 大的项目 View 的组合很复杂, 以及复杂的交互,
首先, React 的架构很方便 View 的扩展, 相比 Backbone 更灵活,
React 的结构更像是后台应用, 一个数据库, 前面是灵活渲染各种的 View.
对此我还是比较乐观的.

和 Backbone 对比

Backbone to React
http://joelburget.com/backbone-to-react/

这哥们写了一篇文章叫这个名字.. 不过看内容的好像不明确啊..
我说一下我现在的考虑的这些事情:

  • 双向绑定

React 其实不是双向绑定, 仅仅是单向的从数据到视图的渲染
问题是 Backbone 没有...
我最近遇到的 DOM 和数据绑定的事情, 觉得大量的手动绑定太痛苦了

  • 状态切换

状态问题比较大, 比如 Backbone 渲染 View, 先用模版, 后用 jQuery
结果是对同个元素的渲染其实有两套方案在发挥作用..
这样的重复肯定会让人累, 其次, jQuery 命令式的操作方式显然是不友好的..

  • 第三方的模块集成

用了 React 后, 对 DOM 的容忍就没那么好了, 至少比 Backbone 要差好多
在 Backbone 里, 强行把 jQuery 写的组件插进来尚且能做到,
在 React 里不用 jQuery, 所以已有的 jQuery 组件能不能直接用要重新思考了

  • 对后端开发人员更友好

Backbone 渲染模版部分和服务端渲染非常相似, 但是到了复杂的消息就不对头了
为了 Backbone 的手法能 work, 要想尽办法转化为 Event 的方式
而 React 从理解上就是每次数据更新渲染整个页面, 没有推荐第二种方式...
就像是原来的, 每个操作刷新页面的思路, 非常清晰,,,
考虑到前后端都是 JS, 这将给后端开发的人带来方便

  • HTML 中空白的问题

最近用的模板引擎没有处理好 HTML 当中奇怪的空白, 导致出现意外的间隔
因为 React 是通过 Virtual DOM 转化的, 这样的空白就是不存在的
我花不少时间想把 Cirru 编译到 JS 模版来解决这个问题, 而 React 原生没就问题

  • 模版语法

HTML 模版中我们避免不了逻辑, 结果还是会插入一些简单的逻辑进去
更麻烦的是, 有时候不想插逻辑的结果就是用 jQuery 去实现这部分逻辑
即便抛开这些, HTML 写多了, 上边这个状态那个状态, 就变得难看懂了

React 的 DOM 是从 JS 的数据结构里生成的, 因此没有维护和编译模版的麻烦,
不过也有人会说 JS 里写 DOM 会很难看, 因为... 反正就是很难看
的确, 当页面变大之后, 究竟会有多复杂我目前不清楚, 需要深入看

  • 数据结果更加随意

Backbone 里有 Collection 作为约束, 当然也提供了一些方便,
但是真实场景的应用将会比较复杂, Collection 共用数据就麻烦不少
最近碰到的例子, 多个 Collection 存在对应同个 User 的多份数据,
如每次都刷新, 从 id 生成界面, 不会有问题, 但是 Backbone 里不方便这么做

  • 数据状态之间的切换

Backbone 麻烦的地方, 在于我们用 jQuery 的时候, 手动维护状态切换
问题是, 可能有多种状态的时候, 就需要有多个状态之间切换的代码
这样的状态维护, 不是一份代码, 而不是状态和状态相乘的结果的代码,
虽然通常界面就是两个状态, 但某种程度上也是重复了一次操作.

期待

我想说 React 真的解决了好多 Backbone 里的问题...
如果要切换, 就要开始考虑 React 引入的新问题是哪些, 能否容忍或者减轻?
以及在大项目当中使用 React 的经验我也觉得不足, 细节上并不能有定论
所以想找机会用 React 尝试一下稍微大一点的项目, 验证可用性


返回博客首页: http://blog.tiye.me/


题叶
17.3k 声望2.6k 粉丝

Calcit 语言作者