如果两个 Flux 商店必须相互依赖怎么办

Posted

技术标签:

【中文标题】如果两个 Flux 商店必须相互依赖怎么办【英文标题】:What if two Flux stores have to depend on each other 【发布时间】:2015-08-30 08:05:18 【问题描述】:

Flux 的目标之一是通过减少疯狂的纠缠依赖项来使应用程序更可预测。使用 Dispatcher,您可以定义更新 Store 的严格顺序。这创建了一个很好的树依赖层次结构。这就是理论。考虑以下情况:

我有一个游戏。位于层次结构顶部的商店是 StateStore,它只保存当前游戏状态,即。 e. 播放中暂停结束。它通过 PAUSERESUME 等操作进行更新。所有其他商店都依赖于此。因此,当商店处理某种更新操作(即 MOVE_LEFT)时,它首先检查 StateStore 以及游戏是否暂停结束,它忽略了这个动作。

现在假设有一个动作会导致游戏结束。它更新了一些商店并且商店决定游戏不应该继续(“游戏角色向左移动并落入陷阱”)。所以StateStore 中的状态应该变为over。我该怎么做?

理论上应该是这样的:

    给定商店首先更新并到达游戏结束点 StateStore 之后会更新(它等待另一个存储),检查另一个存储并将状态切换到over

不幸的是,其他商店也需要访问 StateStore 来检查当前的游戏状态,看看它是否应该更新(即游戏没有暂停)。它们显然相互依赖。

可能的解决方案:

    将这些商店合并为一个商店。这可能会导致我的整个应用程序崩溃到一个单独的商店中,这引发了一个问题,在这种情况下 Flux 是否是一个好主意。 区分更新顺序只读依赖。所有商店都将按照严格的顺序更新,但是它们可以任意相互读取。因此,StateStore 将针对每个操作检查所有现有商店,如果其中任何一个表明游戏结束,它会将状态更改为 over,从而有效地阻止所有其他商店更新。

你怎么看?

【问题讨论】:

你找到解决办法了吗?我现在也有同样的问题.. 我添加了一个可能对你有帮助的答案。 【参考方案1】:

Flux 中的存储应尽可能相互独立,并且不应相互读取。改变它们状态的唯一方法是通过动作。

在您的情况下,如果某个商店决定游戏结束 - 您应该从 ActionCreator 更新 StateStore。您可以通过从商店调用 HaltGameActionCreator 或从最初触发商店更改的 ActionCreator 调度 HALT_GAME 动作来实现。

【讨论】:

阅读和改变是两件不同的事情。在我的示例中,我不需要从另一个商店更改一个商店,我需要从另一个商店读取。此外,在处理前一个动作时不允许分派新动作,并且通过异步分派动作来解决这个问题似乎有点 hacky。在创建者中调度 MOVE_LEFT 后,我可以检查商店的游戏结束,然后在需要时调度 HALT_GAME,但这似乎也不正确。如果 MOVE_LEFT 导致游戏结束,应用程序状态 (StateStore) 应该包含该信息,我不需要其他操作。 @opportunato "商店应该尽可能相互独立":但是Dispatcher 有一个waitFor 方法,几乎​​没有在所有facebook 示例中使用【参考方案2】:

对于那些有同样问题的人,您可以阅读here,了解我遇到此问题的实际应用程序以及我如何解决它。长话短说,我允许所有商店任意读取彼此(建议的解决方案 2)。

请注意,ES6 模块允许循环依赖,从而简化了实现。

不过,回首往事,我不确定这是否是一个正确的决定。如果一个业务逻辑固有地包含一个循环依赖,我们不应该仅仅因为有人这么说就尝试应用一个并不真正支持它的解决方案。 Flux 只是一种模式,还有很多其他的方式来构造代码。因此,也许我会建议将整个逻辑折叠到一个存储中,并使用其他方法之一来实现存储本身(例如标准 OOP 技术)。

我还会考虑使用 redux 和 reselect 而不是 Flux。原始示例的问题在于依赖于两个不同输入的 StateStore。它可以通过用户显式暂停/恢复游戏或通过游戏情况达到游戏结束来更改。这种方法的优点是您只需要检查一个商店即可获得当前的游戏状态。

使用 redux/reselect,您将有一个 reducer 处理暂停/恢复操作,另一个 reducer 处理 游戏情况。然后你会有一个选择器将这两条信息组合成最终的游戏状态。大多数业务逻辑将从商店转移到动作创建者,即在moveLeft() 动作创建者中,您将使用此选择器检查游戏状态,然后您才可以调度MOVE_LEFT 动作。

请注意,这只是一个粗略的想法,我不知道它是否可行。

【讨论】:

很有趣,你会允许商店触发调度吗?也就是说,存储运行操作。这里的含义是商店可以相互发送操作.. 不,我写了 read。他们可以互相阅读。商店无法调度操作,Flux 的默认 Facebook 实现甚至不允许它。您可以通过在动作创建器中调度一系列动作来绕过这个限制,但在这种情况下,它也不是一个好的解决方案。如果一个特定的用户交互导致游戏结束,您不需要两个操作来更新状态。

以上是关于如果两个 Flux 商店必须相互依赖怎么办的主要内容,如果未能解决你的问题,请参考以下文章

在 React/Flux 中管理存储数据依赖

如何处理这两个相互依赖的信号?

Flux 架构一个复杂的商店与两个较小的商店

跨商店的扩展事件发射器功能在 Flux 中发生冲突

谷歌商店怎么解决核对信息?

Flux 中的 AJAX:依赖状态更改时刷新存储