Redux - 多个商店,为什么不呢?

时间:2015-11-09 22:47:36

标签: javascript redux

作为一个注释:我已经阅读了Redux的文档(也是Baobab),并且我已经完成了Googling&测试

为什么强烈建议Redux应用只有一个商店?

我理解单店设置与多店铺设置的优缺点(关于此主题的SO上有很多Q& A )。

IMO,这个架构决策属于应用程序开发人员基于他们的项目'需要。那么为什么Redux如此强烈建议,几乎到了强制性的声音(虽然没有什么能阻止我们制作多个商店)?

编辑:转换为单店后的反馈

在使用redux处理许多人认为复杂SPA之后的几个月之后,我可以说单店结构非常适合使用。

有些观点可能会帮助其他人理解为什么单一商店与许多商店在很多很多用例中都是一个没有实际意义的问题:

  • 它可靠:我们使用选择器挖掘应用状态并获取与上下文相关的信息。我们知道所有需要的数据 在一家商店。它避免了对状态的所有质疑 问题可能是。
  • 它快速:我们的商店目前有近100个减速机,如果不是更多的话。即使按此计算,也只有少数减速器处理数据 任何给定的调度,其他人只返回先前的状态。该 一个巨大/复杂的商店( nbr of reducers )很慢的论点 几乎没有实际意义。至少我们没有看到任何性能问题 来自那里。
  • 调试友好:虽然这是使用redux作为一个整体的最有说服力的论据,但它也适用于单店和多店 商店。构建应用程序时,您必然会遇到状态错误 过程(程序员错误),这是正常的。 PITA就是那些 错误需要几个小时来调试。感谢单店(和 redux-logger )我们从来没有花费超过几分钟的时间 国家问题。

一些指示

构建redux商店的真正挑战在于决定如何构建。首先,因为在路上改变结构只是一个主要的痛苦。其次,因为它在很大程度上决定了您的使用方式,并查询您的应用数据是否适用于任何流程。关于如何构建商店有很多建议。在我们的案例中,我们发现以下是理想的:

{
  apis: {     // data from various services
    api1: {},
    api2: {},
    ...
  }, 
  components: {} // UI state data for each widget, component, you name it 
  session: {} // session-specific information
}

希望这些反馈可以帮助其他人。

编辑2 - 有用的商店工具

对于那些一直想知道如何轻松地"管理单店,这可能会很快变得复杂。有一些工具可以帮助隔离商店的结构依赖性/逻辑。

Normalizr根据架构规范化您的数据。然后,它提供了一个界面来处理您的数据,并通过id获取数据的其他部分,就像字典一样。

当时不知道Normalizr,我沿着同样的路线建造了一些东西。 relational-json采用模式,并返回基于表的界面(有点像数据库)。 relational-json的优点是您的数据结构动态地引用数据的其他部分(本质上,您可以在任何方向上遍历数据,就像普通的JS对象)。它不像Normalizr那样成熟,但我已经在生产中成功使用它几个月了。

6 个答案:

答案 0 :(得分:193)

当您可能使用多个商店时存在边缘情况(例如,如果您在每秒多次同时更新屏幕上数千个项目的列表时遇到性能问题)。这说它是一个例外,在大多数应用程序中,你不需要超过一个商店。

为什么我们在文档中强调这一点?因为大多数来自Flux背景的人会假设多个商店是使更新代码模块化的解决方案。但是,Redux有一个不同的解决方案:减速器组合。

将多个reducers进一步拆分为reducer树,就是如何在Redux中保持模块更新。如果您没有认识到这一点并且在没有完全理解减速器组成的情况下去多个商店,那么您将会错过Redux单店架构的许多好处:

  • 使用reducer组合可以轻松地在Flux中实现“依赖更新”la waitFor,方法是手动调用其他Reducer以及其他信息并按特定顺序编写缩减器。

  • 使用单个商店,可以很容易地保持,保湿和阅读状态。服务器呈现和数据预取是微不足道的,因为只需要在客户端上填充和重新水化一个数据存储,JSON可以描述其内容而不必担心商店的ID或名称。

  • 单个商店使Redux DevTools的时间旅行功能成为可能。它还使像redux-undo或redux-optimist这样的社区扩展变得容易,因为它们在reducer级别上运行。这种“减速剂增强剂”不能用于商店。

  • 单个商店保证只有在处理完发件后才会调用订阅。也就是说,在通知听众时,状态已经完全更新。有很多商店,没有这样的保证。这是Flux需要waitFor拐杖的原因之一。对于单个商店,这不是您首先看到的问题。

  • 最重要的是,Redux中不需要多个商店(除了您应该首先分析的性能边缘情况之外)。我们将其作为文档中的一个重点,因此我们鼓励您学习减速器组合和其他Redux模式,而不是像使用Flux那样使用Redux,并且失去它的好处。

答案 1 :(得分:15)

在一些拥有数百或数千个Reducer的大型企业应用程序中,将应用程序的不同区域视为完全独立的应用程序通常很有用。在那些情况下(实际上是多个共享域名的应用程序),我使用多个商店。

例如,我倾向于将以下常见功能区域视为单独的应用程序:

  • 管理
  • 分析/数据访问仪表板
  • 结算管理&购买流程
  • 企业客户团队/权限管理

如果这些东西中的任何一个很小,只需将它们作为主应用程序的一部分。如果它们变得非常大(如某些企业帐户管理和分析工具那样),请将它们分开。

管理超大型应用的最佳方式是将它们视为许多较小应用的组合。

如果您的应用程序低于~50k LOC,您可能应该忽略此建议并遵循Dan的建议。

如果你的应用程序超过1百万LOC,你可能应该拆分迷你应用程序,即使你将它们保存在单声道回购中。

答案 2 :(得分:3)

在以下用例中,多个商店可能会有所帮助 1.如果您有大型组件在数据结构,行为,应用程序上下文方面彼此独立。隔离这些组件可以更轻松地管理数据和应用程序流。它还有助于组件的独立开发和维护。 2.性能问题:不是典型的用例,但是如果你的某些组件经常更新并且对其他组件没有任何影响,那么你可能会去不同的商店。

对于所有其他情况,您可能不需要拥有多个商店。正如丹所说,创造周到的减速剂成分可以证明是更好的解决方案。

答案 3 :(得分:3)

  

此架构决定属于基于   他们的项目需求

您生活在自己的世界中。我每天都在与使用redux的人见面,因为它很流行。您甚至无法想象没有任何决定就开始重新启动多少项目。我讨厌redux方法,但不得不使用它,因为其他开发人员一无所知。这只是Facebook造成的史诗般的泡沫。

  • 这不可靠,因为部分商店不是孤立的。
  • 效率低下,因为您正在克隆和遍历哈希树。当突变以算术方式增长时,复杂性就会以几何方式增长。您无法通过重构任何化简器,选择器等来修复它。您必须拆分Trie。
  • 速度变慢,没有人希望将其拆分为具有单独存储的单独应用程序。没有人愿意花钱在重构上。人们通常将一些智能组件转换为转储,仅此而已。您知道Redux开发人员正在等待什么未来吗?他们将维持这些地狱。
  • 调试不友好。很难调试商店中几乎隔离的部分之间的连接。甚至很难分析这些连接的数量。

让我们假设您有几个redux商店。您将中断单向数据流。您将立即意识到商店之间有多少联系。您可能会遭受这些连接的困扰,与圆形部门战斗等等。

具有单向流动的单一不可变存储并不是每种疾病的灵丹妙药。如果您不想维护项目体系结构,反正会遭受痛苦。

答案 4 :(得分:2)

为什么我们不能使用Redux使用多个商店?

  

这在Redux中不是必需的,因为数据域之间的分离已经通过将单个reducer拆分为较小的实现   减速器。


我可以还是应该创建多个商店?我可以直接导入我的商店,然后自己在组件中使用它吗?

原始的Flux模式描述了在一个应用程序中有多个“商店”,每个商店都存储着不同的域数据区域。这可能会带来一些问题,例如需要一个商店“ waitFor”另一商店进行更新。

  

这在Redux中不是必需的,因为数据域之间的分离已经通过将单个reducer拆分为较小的实现   减速器。

与其他几个问题一样,可以在页面中创建多个不同的Redux商店,但预期的模式是仅拥有一个商店。拥有一个存储即可启用Redux DevTools,使数据的持久化和水化变得更简单,并简化订阅逻辑。

在Redux中使用多个商店的一些正当理由可能包括:

通过对应用程序进行性能分析确认后,解决由于状态的某些部分更新过于频繁而导致的性能问题。 将Redux应用程序隔离为更大应用程序中的组件,在这种情况下,您可能希望针对每个根组件实例创建一个商店。 但是,创建新商店并不是您的第一本能,特别是如果您来自Flux背景。首先尝试使用reducer composition,如果不能解决您的问题,请仅使用多个商店。

类似地,虽然您可以通过直接导入商店实例来引用商店实例,但是在Redux中这不是推荐的模式。如果创建商店实例并从模块中导出它,它将成为单例。这意味着将Redux应用程序隔离为大型应用程序的组件(如果有必要)或启用服务器渲染将变得更加困难,因为要在服务器上为每个请求创建单独的存储实例。

official doc by redux

答案 5 :(得分:1)

在Redux中拥有一家商店真的是我们在许多情况下所需要的,我使用Redux和Flux并且相信Redux可以更好地完成工作!

不要忘记商店是一个JavaScript对象,所以虽然你只有一个商店,它可以很容易地扩展和重用,对我来说,有一个商店使得使用Redux开发工具更容易遍历而不是在大型应用程序中混淆......

另外一家商店的概念是为我们模仿数据库,一个可以改变它的真相来源,你可以在浏览器内存中访问它......

如果整个应用程序管理良好,一个商店就足以管理整个应用程序状态......