V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
russj
V2EX  ›  JavaScript

使用 Meteor 和 React 开发 Web App

  •  
  •   russj · 2015-11-12 19:54:46 +08:00 · 3720 次点击
    这是一个创建于 3097 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Meteor 和 React 非常适合联合使用。两者的一个匹配特点就是数据的自动响应 - Reactivity 。这种 响应式编程 避免了使用者再写代码来跟踪变量更新的情形,所以代码会更加简洁易维护。

    下面简单对比一下 Meteor 与其他框架或者架构。

    REST

    不同于大多数传统架构, Meteor 没有采用 RESTful 的后端。 Meteor 的客户端和服务器之间的数据交流是基于 Publish-subscribe 模式。 REST API 挺消耗资源的,特别是在移动应用盛行的时代,客户端需要更频繁的存取数据,所以现在一个趋势是用 Restless 架构,例如使用 WebSocket 。不过 REST 、 SOAP 和 WebSocket 都有各自的应用场景。

    Meteor 采用自己开发的一套基于 WebSocket 的简单协议 - DDP 。基本上就是利用 WebSocket 传递 JSON 消息。 DDP 有各种主流平台、语言的实现。支持列表见这里。所以也可以把 Meteor 仅仅当做后端服务来使用。

    Meteor 就是基于以上描述的一个实时框架。所以能够做到以下三个特点:

    • Database Everywhere 前后端都可以直接操作数据库里的数据

    • Latency Compensation 就是 Relay 的 Optimistic Update

    • Full Stack Reactivity. 从数据库到模板,所有层面实时响应、自动更新

    Flux

    Flux 的核心概念是单向数据流,利用观察者模式保证数据源只来自于一个地方。

    image

    如上图。 Flux 主要由三部分: Dispatcher, Store 和 View (React Components) 组成。

    Action (或者叫 Action Creator) 是 Dispatcher 的辅助函数,主要是用来描述由 View 产生的用户互动或者其他触发事件。 Action Creator 会打包用户互动来生成对象,可以看做是 Flux 的第四部分。

    Dispatcher 类似一个中央集线器,由一堆 Store 的回调函数组成。

    Store 负责保存应用的状态和逻辑,在其外部的代码是不涉及数据管理的;它自己也不产生数据,只能从外部获得新数据。 Store 对 Action 进行反馈,然后发出一个数据状态改变的事件。 Controller-View 监听事件,一旦触发就从 Store 获取相应数据。这样就能够保证数据的单向流动,使逻辑更简单。

    Meteor 完全可以作为一种 Flux 的实现。例如使用 FlowRouter 作为 Dispatcher , MiniMongo 作为 Store 。这样可以为 React 带来很好的数据和逻辑状态的管理;反过来, React 也可以为 Meteor 带来前端模块化,单向数据流模式,使代码更少且更好维护;另外 React 的 Virtual Dom 机制也为会 Meteor 前端渲染带来性能上的提高。所以我说他们是 Naturally Fit 。

    meteoreact

    上图就是一个典型的 React Meteor App 。个人感觉好像 Flux 更多是面向 Chat Based App ,所以没有涉及到 routing 。在 Meteor ,很多时候 Router 其实是一个天然的 Dispatcher 。而 Meteor 客户端自带的 MiniMongo 可以作为 Store 。对于 View ,如图中可以使用一个父组件来监听数据的变化,子组件负责界面渲染和互动。另外一个方案是使用高阶组件 (Higher Order Components) HOC 来包裹 UI 组件。高阶组件负责数据查询,子组件负责渲染等。在简单情况下,单个组件就可以了, Controller-View 可以和 UI 渲染在一个 Component 里。如果程序复杂,也可以使用 Meteor 的 Tracker.autorun 来建立一个独立的 Store 。已经有人按照 Flux 的方式把 Facebook 的 Dispatcher 再包装为这个 Meteor 包 Github Repo。不过我认为这样做反而把简单问题复杂化了。也或许我遇到的问题还不够复杂。

    Relay and GraphQL

    Meteor 还没有类似 GraphQL 的包。不过据说正在开发类似的东西,甚至兼容 SQL 数据库。现在 Meteor 官方只支持 MongoDB 。

    对于 Relay ,其实 Meteor 的 Meteor.subscribe 和 MiniMongo 做着类似的事情。下面对比 Meteor 和 Relay 的三个特点

    • Declarative <br/>
      Relay 不使用命令式的 API 来进行数据通信,而使用 GraphQL 申明数据需求,自动获取数据。
      在 Meteor ,如果使用 ReactMeteorData Mixin ,可以获得同样的效果。 getMeteorData 是一个 reactive computation ,所以每次具有响应性的数据变化后,这个函数会被自动调用,再次获得数据。详情参见 这里

    • Colocation <br/>
      数据查询和 View 在一起,这样更容易理解和调试程序。 Relay 还能聚集查询来提高请求数据的效率。对于 Meteor ,前面提到的 ReactMeteorData Mixin 本来就是在 React 的 Component 里,所以也具有 Relay 的托管特点。

    • Mutations <br/>
      Relay 允许通过 GraphQL 在客户端和服务器端修改数据,并且自动做到数据的一致性,乐观更新 (Optimistic Update)。 Meteor 的 MiniMongo 也具有这些特征。前面在 REST 部分提到的 Meteor 三个特点, Database Everywhere 和 Full Stack Reactivity 就是指在前后端存取数据,自动保持数据的一致性;而 Latency Compensation 其实就是 Optimistic Update 。另外从 这篇文章 看起来, Relay 在数据的 Reactive 方面做得还不够,前后端都还要写一些数据的更新逻辑,甚至得通过 polling 来达到数据的实时更新。

    小结

    随着 Relay 和 GraphQL 的发布,感觉 Facebook 正在开发和 Meteor 同类型的前后端完整框架,而不是仅仅局限于前端 View 。

    其实 Facebook 没有发明任何新概念,只是把很多传统的软件开发实践用到了前端领域。随着移动应用的广泛传播和前端开发的复杂化, React 生逢其时,把前端工程化向前推了一步。

    Disclaimer: 对于 Relay 我没有实际经验,都是通过 Facebook 的文档来了解,如果理解有偏差,欢迎纠正讨论。

    2 条回复    2015-11-13 01:07:45 +08:00
    timqian
        1
    timqian  
       2015-11-13 00:31:09 +08:00 via Android
    你用的是 meteor-react 吗?上次更新是 6 个月前。。。
    russj
        2
    russj  
    OP
       2015-11-13 01:07:45 +08:00
    @timqian
    用这个
    https://atmospherejs.com/meteor/react
    10 月 31 号最后更新的
    meteor add react
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4465 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 04:08 · PVG 12:08 · LAX 21:08 · JFK 00:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.