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

备注:我已经阅读了Redux (Baobab)的文档,并且我已经做了相当一部分的google &测试。

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

我理解单店设置与多店设置的利弊(在这个问题上有很多关于SO的问答)。

在我看来,这种架构决策应该由应用程序开发人员根据他们的项目需求做出。那么,为什么强烈建议Redux使用它,几乎到了听起来强制的地步(尽管没有什么能阻止我们多开商店)?

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

在与redux一起工作了几个月之后,我可以说,这种单一的商店结构是一种纯粹的乐趣。

以下几点可能有助于其他人理解为什么在许多用例中,单店vs多店是一个没有意义的问题:

  • 它是可靠的:我们使用选择器来挖掘应用程序的状态并获得上下文相关的信息。我们知道所有需要的数据 是在一家单店。它避免了所有关于国家在哪里的问题
  • 它的速度非常快:我们的商店目前有接近100个减速器,如果不是更多。即使是这样,也只有少数减速器处理数据 任何给定的分派,其他分派只返回之前的状态。的 一个巨大/复杂的存储(还原剂的丁腈橡胶)是缓慢的 没什么意义。至少我们没有看到任何性能问题
  • 调试友好:虽然这是一个将redux作为一个整体使用的最有说服力的参数,但它也适用于单个存储和多个存储 商店。在构建应用程序时,一定会出现状态错误 process (程序员的错误),这是正常的。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获取数据的其他部分,很像Dictionary。

当时我还不知道Normalizr,所以我按照同样的思路构建了一些东西。relational-json接受模式,并返回一个基于表的接口(有点像数据库)。relational-json的优点是你的数据结构动态引用数据的其他部分(本质上,你可以遍历你的数据在任何方向,就像普通的JS对象)。它不像Normalizr那样成熟,但几个月来我一直在生产环境中成功地使用它。

102585 次浏览

当你可能使用多个商店时,也存在一些边缘情况(例如,如果你在每秒多次更新屏幕上同时出现的数千个项目的列表时遇到性能问题)。这是一个例外,在大多数应用中,你只需要一个以上的商店。

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

将多个减速器进一步分解为一个减速器树,这是在Redux中保持更新模块化的方法。如果你没有意识到这一点,在没有完全理解减速器组成的情况下就去多个存储,你将错过Redux单存储架构的许多好处:

  • 通过使用reducer组合,可以很容易地实现Flux中的waitFor那样的“依赖更新”,方法是手动编写一个reducer,并以特定的顺序调用其他带有额外信息的reducer。

  • 使用一个存储,就很容易坚持、补充和读取状态。服务器呈现和数据预取是微不足道的,因为只有一个数据存储需要在客户端上进行填充和补水,JSON可以描述其内容,而无需担心存储的ID或名称。

  • 一个单一的商店使Redux DevTools的时间旅行功能成为可能。它还使redux-undo或redux-optimist等社区扩展变得容易,因为它们在reducer级别上操作。这样的“减速器增强器”不能为商店编写。

  • 单个存储可以保证仅在处理分派之后才调用订阅。也就是说,在通知侦听器时,状态已经完全更新。对于许多商店来说,没有这样的保证。这是Flux需要waitFor拐杖的原因之一。对于单个商店,这不是您首先看到的问题。

  • 最重要的是,在Redux中多个存储是不必要的(除了性能边缘情况,无论如何您都应该首先分析这些情况)。我们在文档中把它作为一个重要的点,所以我们鼓励你学习减速器组合和其他Redux模式,而不是把Redux当作Flux来使用,从而失去它的好处。

多个存储在以下用例中是有帮助的 1. 如果你有大型组件,它们在数据结构、行为和应用程序上下文方面彼此独立。隔离这些组件可以更容易地管理数据和应用程序流。它还有助于组件的独立开发和维护。 2. 性能问题:不是一个典型的用例,但是如果你的一些组件非常频繁地更新,并且对其他组件没有任何影响,也许你可以选择不同的存储

对于所有其他情况,您可能不需要多个存储区。正如丹所说,创造周到的减速器组合可以证明是更好的解决方案。

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

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

  • 管理
  • 分析/数据可见仪表板
  • 计费管理;购买流程
  • 企业帐号组/权限管理

如果这些东西很小,就把它们作为主应用程序的一部分。如果它们变得非常大(如一些企业客户管理&分析工具可以),将它们分开。

管理大型应用程序的最佳方法是将它们视为许多小型应用程序的组合。

如果你的应用LOC少于5万,你就应该忽略这个建议,转而听从Dan的建议。

如果你的应用程序的LOC超过100万,你可能就应该把小应用拆分出来,即使你是在单一回购模式下维护它们。

在Redux中拥有一个商店确实是我们在许多情况下所需要的,我同时使用Redux和Flux,并且相信Redux做得更好!

不要忘记商店是在一个JavaScript对象中,所以当你只有一个商店时,它可以很容易地扩展和重用,对我来说,拥有一个商店可以更容易地使用Redux开发工具进行遍历,并且不会与大型应用程序混淆……

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

如果整个应用程序管理得很好,那么一个存储就足以管理整个应用程序的状态……

这个架构决策属于应用程序开发人员所基于的 他们的项目需求

.

你活在自己的世界里。我遇到一些使用redux的人,因为它很流行,每天都在使用。你甚至无法想象有多少项目在没有任何决定的情况下开始重做。我讨厌redux方法,但不得不使用它,因为其他开发人员对此一无所知。这只是一个被facebook吹大的史诗般的泡沫。

  • 不可靠,因为存储的部分不是孤立的。
  • 这是低效的,因为你正在克隆和遍历哈希树。当突变呈算术增长时,复杂度呈几何增长。你不能通过重构任何约简器、选择器等来修复它。你必须把你的三叉分开。
  • 当它变慢时没有人想把它分割成单独的应用程序和单独的存储。没有人愿意在重构上花钱。人们通常是将一些智能组件转换为转储,就是这样。你知道redux开发者的未来是怎样的吗?他们会维持这些地狱。
  • 它对调试不友好。很难调试存储中实际上孤立的部分之间的连接。甚至很难分析这些连接的数量。

让我们假设您有几个redux存储。您将打破单向数据流。你会立刻意识到你在商店之间有多少联系。你可能会遭受这些连接,与圆形deps战斗等。

单向流动的单一不变存储并不是所有疾病的万能药。如果您不想维护项目架构,那么无论如何您都会受到影响。

为什么我们不能使用多个存储使用redux????

这在Redux中是不必要的,因为数据域之间的分离已经通过将单个减速器分成更小的来实现 还原剂。< /强> < / p >

我是否可以创建多个商店?我可以直接导入我的商店,并自己在组件中使用它吗?

最初的Flux模式描述了在一个应用程序中有多个“商店”,每个商店都拥有不同的领域数据区域。这可能会带来一些问题,比如需要让一个商店“等待”另一个商店更新。

这在Redux中是不必要的,因为数据域之间的分离已经通过将单个减速器分成更小的来实现 还原剂。< /强> < / p >

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

在Redux中使用多个存储的一些有效原因可能包括:

解决由于某些状态的频繁更新导致的性能问题,当通过分析应用程序确认时。 将Redux应用程序隔离为更大应用程序中的组件,在这种情况下,您可能希望为每个根组件实例创建一个存储。 然而,创建新店不应该是你的第一直觉,特别是如果你来自Flux背景。首先尝试减速器组合,如果不能解决你的问题,只使用多个存储

类似地,虽然可以通过直接导入引用存储实例,但在Redux中不推荐使用这种模式。如果你创建了一个存储实例并从一个模块导出它,它将变成一个单例。这意味着,如果有必要的话,将Redux应用程序隔离为一个更大的应用程序的组件将更加困难,或者启用服务器呈现,因为在服务器上,您希望为每个请求创建单独的存储实例。

官方doc by redux

为什么强烈建议Redux应用程序只有一个商店?< / >强

Redux有3个主要原则:

< em > 1. 真相的单一来源: 整个应用程序的状态存储在一个对象中

< em > 2. 状态为只读: 改变状态的唯一方法是发出一个动作

< em > 3.使用纯函数进行更改: "你把约简写成纯函数来指定 动作转换状态树的具体方式。"

所以如果我们使用多个存储,那么它也可能违反原则1。虽然你可以使用多个REDUCERS,在某些情况下,这将是非常非常有帮助的。 由于多个存储,我们可能遇到的一些问题是

以下
  1. 很难调试。
  2. 放慢速度。
  3. 它可能有多个真实源,因此可能导致多个运行时错误。

https://www.educative.io/courses/building-teslas-battery-range-calculator-with-react-and-redux/qVZRXlwQxv7