【问题标题】:From AngularJS to Flux - The React Way从 AngularJS 到 Flux - React 方式
【发布时间】:2015-01-31 14:08:12
【问题描述】:

作为一名拥有良好实践 AngularJS 经验的开发人员,我如何调整我使用 React 在 Flux 中编写 Web 应用程序的心智模型?

我不是在寻找 Flux+React 与 Angular 的答案(网上已经有很多),但我想知道在两种“心态”:之前,我被介绍到The Angular Way;比较而言,React Way 是什么?

当我离开 Angular 世界并过渡到 Flux 时,我需要开始关注关键事项有哪些?

首先是不同,现在是相似:AngularJS 非常固执己见,并且有一些非常大的禁忌,比如 - 不要将 UI/DOM 代码放在控制器中。 React 的最大禁忌和观点是什么?

最后但同样重要的是,Facebook 将 Flux 称为 MVC 的替代品,但正如我所看到的那样 - React 是视图引擎,商店是专注于单个域的模型容器,并且调度程序和动作形成一个控制器。那么这实际上是不是换了一个名字的 MVC 呢?

【问题讨论】:

  • 我没有使用 Angular 的经验,因此很难解释两者之间的差异和过渡过程。但是关于问题的第二部分:React 只是来自 MVC 的 V,我会将它与 Mustache / Marionette 进行比较。 Flux 有 store 和 dispatcher,它们与 React 一起创建了 MVCish 结构。你也可以很容易地用 Backbone 替换 Flux。
  • 在我看来,Flux 是一种反模式。将所有商店耦合到单个调度员,无论其抽象级别和责任如何,都会导致庞大的调度程序块与管理的噩梦。
  • @DmitriZaitsev Flux 没有强制要求每页只有一个调度程序。您可以在同一页面上拥有尽可能多的调度程序来处理不同类型的操作。
  • @bluecollarcoder that 不是反模式吗?考虑通过单个调度程序汇集所有操作的调试好处?
  • 为什么这是一个反模式?与 1 个相比,拥有 2 个或 3 个调度程序真的会导致更多的调试开销吗?根据我的经验,通常最好将组件隔离到尽可能小的空间,尤其是事件总线。拥有一个大型的全局事件总线意味着您的操作/事件会传播到各处,从而增加发生冲突和意外行为的可能性。另外,请参阅 @DmitriZaitsev 对大型调度程序块的评论。

标签: javascript angularjs architecture reactjs reactjs-flux


【解决方案1】:

我会让其他人与 Angular 进行比较/对比,但这里是您的两个问题的一些答案。

那么这实际上不是具有不同名称的 MVC 吗?

Flux 中数据/逻辑层和视图层之间的关注点分离的存在并不使其成为 MVC。许多其他模式也有类似的分裂,最值得注意的是 CQRS,可以说是 Flux 的近亲。在 MVC 意义上,Flux 中没有控制器。 Actions 和 Dispatcher 不等同于控制器。控制器视图很接近,但实际上在它们类似于控制器的方面非常有限。一个关键的区别是 MVC 控制器包含应用程序逻辑并根据模型进行操作。相比之下,Flux 存储包含所有应用程序逻辑并且没有设置器。

当我离开 Angular 世界并过渡到 Flux 时,我需要开始关注哪些关键事项?

Flux 的关键值:

  • 简单大于复杂。
  • 程序员的心智模型至少与代码本身一样重要。
  • 应用程序的各个部分应高度解耦,并尽可能“了解”其他部分。
  • 控制反转:所有控制都应驻留在管理状态的存储区中。商店不采取行动,而是通过行动通知。
  • 应用程序应在发展过程中保持弹性和灵活性,以便更快、更轻松地开发新的、意想不到的功能。

Flux 中的关键概念:

  • 单向数据流:Action → Dispatcher → Stores → Views
    • 每个状态变化和所有新数据都以分派的动作开始。
    • 这个四步数据流是 Flux 程序员的核心心智模型。
  • 分派导致应用程序状态的应用程序范围的转换。
    • 这是一个时刻,正在创建变化的快照。这很容易推理。
    • 我们不能在分派时分派并保持这种简单性。因此,任何必然的变化都必须由最初的行动驱动。
  • 通量存储是域模型,而不是 ORM 模型。它们包含所有逻辑并管理应用程序中特定逻辑域的所有状态。它们可能包含集合、奇异值或两者的组合。
  • Flux 假设派生数据——其中一个存储依赖于另一个存储中的更改——在模型或存储管理规范化数据的复杂应用程序中是一种可能性。为了解决这个问题,Flux Dispatcher 应该公开一种机制来以声明方式管理此依赖关系在商店中。在 Facebook 的 Dispatcher 中,这是通过 waitFor() 方法完成的。这允许一家商店等待另一家商店对某项操作的响应,然后再继续进行自己的响应。

Flux 应用程序的主要部分:

  • Actions:包含新数据和特定类型的对象字面量, 允许商店辨别它是否与其域相关。
  • Dispatcher:回调的注册表,通过回调, 向注册者(商店)分发一个有效负载(一个动作)。它没有自己的智慧。所有情报都在商店中。
  • Stores:向 Dispatcher 注册自身并在其状态发生更改时发出“更改”事件的域模型。
  • Controller-views:查看组件树根附近的组件。他们监听商店中的“更改”事件,并通过商店公开的 getter 方法检索新数据并将其传递给他们的孩子来响应此事件。 Controller-views 和 Views 之间的唯一区别是这个监听功能。
  • 视图:控制器视图组件的无状态子组件,接收和传递数据,很像纯函数。视图和控制器视图最常使用 React 实现,因为它提供了随意重新渲染的能力,而性能损失很小。
  • Utils:可以在不同模块之间轻松共享的纯函数库。

概述,深入:http://facebook.github.io/flux/docs/overview.html

教程:http://facebook.github.io/flux/docs/todo-list.html

示例:https://github.com/facebook/flux/tree/master/examples

Actions 和 Dispatcher:http://facebook.github.io/react/blog/2014/07/30/flux-actions-and-the-dispatcher.html

测试:http://facebook.github.io/react/blog/2014/09/24/testing-flux-applications.html

更多信息:http://facebook.github.io/react/blog/2014/10/17/community-roundup-23.html

【讨论】:

  • 谢谢。您能否扩展关键概念#4?具体而言:“Flux 假设派生数据——一个存储依赖于另一个存储的更改——在模型或存储管理规范化数据的复杂应用程序中是一种可能性。” (机制部分清晰)。谢谢。
  • 当一个应用程序有规范化的数据,也就是它不会在两个地方重复数据(因为这很难维护),我们经常会遇到这样的情况,即Store A中的数据是在商店 B 中需要。例如,构建贺卡的应用程序中的 ImageStore 与 ThemeStore。每个主题可以包含不同的最大图像数量。 ImageStore 需要知道选择了哪个主题,因此它知道可以将多少个主题标记为有效。当 THEME_SELECTED 类型的 action 被派发时,ImageStore 需要等待 ThemeStore,然后获取所选主题的最大值。
  • 处理派生数据实际上是 Facebook 开发 Flux 的最初原因。然而,后来出现了很多好处。
  • 谢谢!我确实看过那个讲座,Jing 评论了他们在派生数据方面遇到的困难,但没有建立联系。请问数据规范化是在服务器端还是客户端进行?也许这是给定的(客户端?),但我自己没有信心回答这个问题。
  • 请您发表评论?
猜你喜欢
  • 2015-04-07
  • 2015-09-12
  • 1970-01-01
  • 2015-02-16
  • 2016-12-03
  • 2016-08-20
  • 2016-03-07
  • 1970-01-01
  • 2015-05-03
相关资源
最近更新 更多