注:我已经阅读了Redux (Baobab也是)的文档,并且我也做了相当一部分的谷歌搜索和测试。

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

我理解单店和多店的利弊(关于这个问题有很多问答)。

在我看来,这种架构决策应该由应用程序开发人员根据他们的项目需求做出。那么,为什么Redux如此强烈地推荐它,几乎是强制性的(尽管没有什么能阻止我们创建多个商店)?

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

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

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

it's reliable: we use selectors to dig through the app state and obtain context-relevant information. We know that all the needed data is in a single store. It avoids all questioning as to where state issues could be. it's fast: our store currently has close to 100 reducers, if not more. Even at that count, only a handful of reducers process data on any given dispatch, the others just return the previous state. The argument that a huge/complex store (nbr of reducers) is slow is pretty much moot. At least we've not seen any performance issues coming from there. debugging friendly: while this is a most convincing argument to use redux as a whole, it also goes for single store vs multiple store. When building an app you're bound to have state errors in the process (programmer mistakes), it's normal. The PITA is when those errors take hours to debug. Thanks to the single store (and redux-logger) we've never spent more than a few minutes on any given state issue.

几点建议

构建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那样成熟,但几个月来我一直在生产环境中成功地使用它。


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

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

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

Using reducer composition makes it easy to implement "dependent updates" a la waitFor in Flux by writing a reducer manually calling other reducers with additional information and in a specific order. With a single store, it's very easy to persist, hydrate, and read the state. Server rendering and data prefetching is trivial because there is just one data storage that needs to be filled and rehydrated on the client, and JSON can describe its contents without worrying about store's ID or name. A single store makes Redux DevTools time travel features possible. It also makes community extensions like redux-undo or redux-optimist easy because they operate on the reducer level. Such "reducer enhancers" can't be written for stores. A single store guarantees that the subscriptions are called only after the dispatch has been processed. That is, by the time listeners are notified, the state has been fully updated. With many stores, there are no such guarantees. This is one of the reasons Flux needs the waitFor crutch. With a single store, this is not a problem you see in the first place. Above all, multiple stores are unnecessary in Redux (except for performance edge cases which you are supposed to profile first anyway). We make it an important point in the docs so you are encouraged to learn reducer composition and other Redux patterns instead of using Redux as if it was Flux, and losing its benefits.


Multiple stores can be helpful in the following use cases 1. If you have large components that are independent of each other in terms of data structure, behavior, application context. Isolating these components make it easier to manage your data and application flow. It also helps independent development and maintenance of your components. 2. Performance problems: not a typical use case, but if some of your components are updating very frequently and does not have any impact on other components, probably you can go for different stores.

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


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

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

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

如果这些东西很小,就把它们作为主应用的一部分。如果它们变得非常大(就像一些企业账户管理和分析工具所做的那样),就把它们分离出来。

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

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

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


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

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

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

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


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

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

It's not reliable because parts of store are not isolated. It's inefficient because you are cloning and traversing hash trie. When mutations grows arithmetically - complexity grows geometrically. You couldn't fix it by refactoring any reducers, selectors, etc. You have to split your trie. When it become slow nobody wants to split it into separate applications with separate stores. Nobody wants to spend money on refactoring. People are usually converting some smart components into dump and that's it. Do you know what future is waiting for redux developers? They will maintain these hells. It's not debugging friendly. It's hard to debug connections between virtually isolated parts of store. It is very hard even to analyze the amount of these connections.

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

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


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

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


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

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

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

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

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

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

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

redux的官方文件


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

Redux有3个主要原则:

1. 真相的单一来源: 整个应用程序的状态存储在一个对象中 一棵树在一家商店里。”

2. 状态为只读: 改变状态的唯一方法是发出一个动作 这就是所发生的事情。”

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

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

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

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