我应该在哪里存储 Redux 中间件的本地状态?

Where should I store the local state of a Redux middleware?

我正在使用 Redux 来管理音乐播放器的逻辑。当它正在播放某些内容并突然失败时,我希望能够拦截该动作并让播放器重新开始,但只有 n 次,因为如果问题不是,我不想一直自动重试可恢复。

我认为中间件是实现这一点的好选择,但我想知道我是否应该在全局状态或中间件本地存储已针对某个项目完成的重试次数。

一个更普遍的问题是 Redux 中间件是否应该包含任何本地状态,我的意思是,只有它关心的状态。

我认为(基于关于您的特定项目的有限信息):

  • 您应该通过中间件构造函数配置 n 值,并且
  • 您应该将 ntotalRetries 都存储在中间件的私有变量中。

为什么?

选择中间件状态的存储位置与 deciding between component state and redux state 有相似之处。您可以使用相同的问题作为指导:

  • Do other parts of the application care about this data?
  • Do you need to be able to create further derived data based on this original data?
  • Is the same data being used to drive multiple components?
  • Is there value to you in being able to restore this state to a given point in time (ie, time travel debugging)?
  • Do you want to cache the data (ie, use what's in state if it's already there instead of re-requesting it)?
  • Do you want to keep this data consistent while hot-reloading UI components (which may lose their internal state when swapped)?

正如丹·阿布拉莫夫所说:

The way I classify it is when ever state needs to be shared by multiple components or multiple pages and we need to persist some data over route changes, all that data should go inside the redux store.

您可以将这个想法从组件映射到中间件,方法是重新表述“…在路由更改时保留一些数据…”到“…在[插入时保留一些数据]此处的相关边界]…”,例如关闭并重新启动应用程序。

  1. totalRetries 似乎不代表应用程序的有意义状态。它与一些 "behind-the-scenes" I/O 操作有关,这些操作不会在关闭应用程序或与调试器共享应用程序状态时持续存在。甚至有人可能会争辩说,您 不应该 通过 redux 状态将它暴露给其他组件,以免它们依赖(可能转移)中间件的内部工作。

  2. redux-saga 等允许我们以非常简洁和可测试的方式编写此类功能,而无需在应用程序状态或模块命名空间中使用 "exposed wires"。您可以使用传奇来封装整个 "play audio" 行为。

  3. 导出一个 reducer 然后从你的中间件访问它的分隔 "public" 状态会引入很多不必要的复杂化。

  4. 如果您想要totalRetriesn暴露给其他组件,您可以通过一个动作来实现,例如PLAY_AUDIO_RETRY 其负载中包含两个变量的操作。