作为说明:我已经阅读了 Redux 的文档(也是猴面包树),并且我已经完成了相当一部分的谷歌搜索和测试。
为什么强烈建议 Redux 应用程序只有一个商店?
我了解单店设置与多店设置的优缺点( 关于此主题的 SO 有很多问答 )。
IMO,这个架构决定属于应用程序开发人员根据他们的项目需求。那么为什么强烈建议 Redux 使用它,几乎到了听起来是强制性的程度( 尽管没有什么能阻止我们创建多个商店 )?
编辑:转换为单店后的反馈
在与 redux 合作了几个月后,许多人认为这是一个复杂的 SPA,我可以说单一商店结构是一种纯粹的工作乐趣。
有几点可以帮助其他人理解为什么在很多很多用例中单店与多店是一个没有实际意义的问题:
一些指示
构建 redux store 的真正挑战是决定如何 构建 它。首先,因为在路上改变结构只是一个主要的痛苦。其次,因为它在很大程度上决定了您将如何使用以及查询您的应用程序数据以获取任何进程。关于如何构建商店有很多建议。在我们的案例中,我们发现以下是理想的:
{ apis: { // data from various services api1: {}, api2: {}, ... }, components: {} // UI state data for each widget, component, you name it session: {} // session-specific information }
希望此反馈对其他人有所帮助。
对于那些一直想知道如何“轻松”管理 单个商店 的人,这很快就会变得复杂。有一个工具可以帮助隔离商店的结构依赖/逻辑。
Normalizr可以根据模式对您的数据进行规范化。然后它提供了一个接口来处理您的数据并通过 获取数据的其他部分id,就像字典一样。
id
当时不知道 Normalizr,我按照相同的思路构建了一些东西。关系 json接受一个模式,并返回一个基于表的接口( 有点像数据库 )。关系 json 的优点是你的数据结构可以动态地引用数据的其他部分( 本质上,你可以在任何方向遍历你的数据,就像普通的 JS 对象一样 )。它不像 Normalizr 那样成熟,但我已经在生产中成功使用了几个月。
当您可能使用多个商店时(例如,如果您在每秒多次同时更新屏幕上的数千个项目的列表时遇到性能问题)。也就是说,这是一个例外,在大多数应用程序中,您只需要一个商店即可。
为什么我们在文档中强调这一点?因为大多数来自 Flux 背景的人会 认为多个商店是使更新代码模块化的解决方案。 然而 Redux 对此有不同的解决方案:reducer 组合。
将多个 reducer 进一步拆分为一个 reducer 树是您在 Redux 中保持更新模块化的方式。如果你没有意识到这一点,在没有完全理解 reducer 组成的情况下就去多个 store,你会错过 Redux 单 store 架构的许多好处:
使用 reducer 组合可以很容易地waitFor在 Flux 中实现“依赖更新”,方法是编写一个 reducer,手动调用具有附加信息的其他 reducer,并按特定顺序。
waitFor
使用单个存储,很容易持久化、补充和读取状态。服务器渲染和数据预取是微不足道的,因为只有一个数据存储需要在客户端进行填充和再水化,并且 JSON 可以描述其内容而无需担心存储的 ID 或名称。
单个商店使 Redux DevTools 时间旅行功能成为可能。它还使 redux-undo 或 redux-optimist 等社区扩展变得容易,因为它们在 reducer 级别上运行。这样的“reducer enhancers”不能写给stores。
单个商店保证仅在处理了调度后才调用订阅。也就是说,在通知侦听器时,状态已完全更新。对于许多商店,没有这样的保证。这是 Flux 需要waitFor拐杖的原因之一。对于一家商店,这不是您首先看到的问题。
最重要的是,在 Redux 中不需要多个存储(除非您应该首先分析性能边缘情况)。我们在文档中强调了这一点,因此鼓励您学习 reducer 组合和其他 Redux 模式,而不是像使用 Flux 一样使用 Redux,从而失去它的好处。