Flux的目标之一是通过减少疯狂纠结的依赖关系来使应用程序更具可预测性。使用Dispatcher,您可以定义更新商店的严格顺序。这创建了一个很好的树依赖层次结构这就是理论。请考虑以下情况:
我有一个游戏。位于层次结构顶部的商店是 StateStore ,它仅包含当前游戏状态,即。即播放,暂停,结束。它通过 PAUSE 或 RESUME 等操作进行更新。所有其他商店都依赖于这个。因此,当商店处理某种更新操作(即 MOVE_LEFT )时,它首先检查StateStore,如果游戏暂停或 over ,它忽略了行动。
现在让我们说有一个动作会导致游戏结束。它更新了一些商店,商店决定游戏不应该继续(“游戏角色向左移动并陷入陷阱”)。所以StateStore中的状态应该改为 over 。我该怎么做?
理论上,它应该是这样的:
不幸的是,其他商店也需要访问StateStore以检查当前的游戏状态以查看它是否应该更新(即游戏没有暂停)。他们显然相互依赖。
可能的解决方案:
您怎么看?
答案 0 :(得分:2)
在Flux商店中应尽可能相互独立,不应相互阅读。改变状态的唯一方法是通过行动。
在您的情况下,如果某个商店决定游戏结束 - 您应该从ActionCreator更新StateStore。您可以通过从商店调用HaltGameActionCreator或从ActionCreator调度HALT_GAME操作来首先触发商店更改。
答案 1 :(得分:1)
对于那些遇到相同问题的人,您可以阅读here关于我遇到此问题的实际应用程序以及我如何处理它。长话短说,我允许所有商店互相任意阅读(建议的解决方案2)。
请注意,ES6模块允许循环依赖,这简化了实现。
然而,回头看,我不确定这是不是一个正确的决定。如果一个业务逻辑固有地包含循环依赖,我们不应该尝试应用一个不真正支持它的解决方案,因为有人这么说。 Flux只是一种模式,还有很多其他方法来构造代码。所以也许我会建议将整个逻辑折叠到一个存储中,并使用其他方法之一来实现存储本身(例如标准OOP技术)。
我还会考虑将redux与reselect一起使用,而不是使用Flux。原始示例的问题在于StateStore依赖于两个不同的输入。它可以通过用户明确暂停/恢复游戏,或通过游戏情境到达游戏结束来更改。这种方法的优点是您只需要检查一个商店即可获得当前的游戏状态。
使用redux / reselect,您将有一个reducer处理暂停/恢复操作,另一个reducer处理游戏情境。然后你会有一个选择器将这两个信息组合成最终的游戏状态。大多数业务逻辑将从商店移动到动作创建者,即在moveLeft()
动作创建者中,您将使用此选择器来检查游戏状态,然后才会发送MOVE_LEFT
行动。
请注意,这只是一个粗略的想法,我不知道它是否可行。