【发布时间】:2016-02-10 17:27:40
【问题描述】:
作为说明:我已经阅读了 Redux 的文档(也是猴面包树),并且我已经完成了相当多的谷歌搜索和测试。
为什么强烈建议 Redux 应用只有一个商店?
我了解单店设置与多店设置的优缺点(关于这个主题有很多关于 SO 的问答)。
IMO,此架构决策属于应用开发人员根据其项目的需求。那么为什么强烈建议 Redux 使用它,几乎到了听起来是强制性的程度(尽管没有什么能阻止我们创建多个商店)?
编辑:转换为单店后的反馈
在与 redux 合作几个月后,在许多人认为复杂的 SPA 上,我可以说单一商店结构是一种纯粹的工作乐趣。
以下几点可能有助于其他人理解为什么在很多很多用例中单店与多店是一个没有实际意义的问题:
- 可靠:我们使用选择器来挖掘应用程序状态并获取与上下文相关的信息。我们知道所有需要的数据 在一个商店里。它避免了所有关于状态在哪里的问题 问题可能是。
- 很快:我们的商店目前有将近 100 个减速器,如果不是更多的话。即使这样算,也只有少数 reducer 处理数据 任何给定的调度,其他的只是返回之前的状态。这 一个巨大/复杂的存储(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 接受一个模式,并返回一个基于表的接口(有点像数据库)。关系 json 的优点是您的数据结构可以动态引用数据的其他部分(本质上,您可以在任何方向上遍历数据,就像普通的 JS 对象)。它不如 Normalizr 成熟,但我已经在生产环境中成功使用了几个月。
【问题讨论】:
-
我喜欢您使用的商店结构的方法;但是,您如何处理映射到组件状态更改的 api 状态更改?假设我从我的 API 接收特定领域的数据,这如何转化为可以在我的组件中找到的通用数据结构?
-
您的组件如何映射/使用存储数据完全取决于您。虽然我认为我不完全理解您的问题,但您能否详细说明或开始聊天会话?
-
我想问题是:您的组件是从 apis 状态渲染任何内容,还是只渲染放入组件状态的任何内容。我怀疑如果您设法仅从组件的状态进行渲染,那么您已经找到了一种极好的方法来使您的组件和容器即使在存在域特定数据的情况下也具有高度可重用性。如果您的组件部分从 API 状态和组件状态呈现,那么我猜您正在利用特定于域的容器将 apis 中的数据映射到您的组件理解的通用列表和原语。
-
我将 Redux 与选择器结合使用,选择器基本上是记忆化的功能纯数据映射器。每个组件“做出反应”以存储更新,如果更改与它相关,它会“选择”数据并相应地呈现。所以是的,组件仅根据对他们而言重要的内容进行渲染。但这不仅仅是因为 Redux 或存储结构。这是由于结合了不可变数据存储、数据更改的引用比较测试以及以组件需要的格式获取组件所需数据的纯选择器。
-
嘿@SebastienDaniel,您能否举例说明您如何实施检查每个组件以了解商店更新中的更改是否与其相关?我的意思是,如果您使用的是某种通用模式……或者在每个特定情况下,您都在检查特定组件相关数据是否已更改。
标签: javascript redux