React/Flux - 为什么我需要一个action-dispatcher?

7
我明白我需要一个emit.change()分发器,让所有的组件都知道存储器内部发生了变化。但我不明白为什么我需要分派操作而不是直接从操作内部调用存储器。
也就是说,我为什么要这样做:
var Dispatcher = require('dispatcher');
var MyActions = {
    addItem: function(item){
        Dispatcher.dispatch({
              action: 'ADD_ITEM',
              payload: item       
       })
    }
}

相比之下:

var MyStore = require('mystore');
var MyActions = {
    addItem: function(item){
        MyStore.addItem(item);
    }
}

这是针对多个商店同时监听同一事件的情况,例如当 StoreAStoreB 同时监听 ADD_ITEM 事件时?

1个回答

9
调度程序在被调用时逐个触发操作。你需要一个调度程序,因为:
  1. 你希望应用程序状态原子性地改变。这意味着,在同步方式下 s1->s2(a1),s2->s3(a2)。而不是 s1->s3(因为 a1 和 a2)。如果你不这样做,你将不得不担心其他操作和这个特定操作一起触发,并猜测所有这些组合的应用程序状态将如何改变。这就是所有混乱的源头,你的代码将变得难以维护。想象一下,在存储中为每个操作编写一个 if-else 块,以检查其他操作是否也处于活动状态。 调度程序确保它不会在已经 dispatching 的情况下分派。一次只有一个 dispatch。使你的状态树非常健康。

  2. 此外,调度程序维护一个回调数组,用于每个“action”触发回调。这对于为相同操作调用多个存储库上的回调非常有用。当存储库订阅操作(使用 register)时,调度程序添加与之关联的 registerHandler 并将其添加到数组中。借助此功能,您可以在需要时注册/注销存储库。并根据操作类型,您可以相应地对所有已注册的存储库进行更改。如果你不使用调度程序,则必须在编写操作部分时担心所有需要通知的存储库。 糟糕!

  3. 采用这种方法,你唯一需要关注的就是向调度程序发送一个操作。其余的都由调度程序处理,通知所有需要基于操作 change 的存储库。由于存储库具有触发视图的回调函数,因此只要需要,这些回调函数就可以被调用。这使得你的代码非常模块化。


感谢您给出的精彩答案!我有另一个相关问题,这也是我来到这个问题的原因。我需要从一个操作中返回一个值(新创建项的ID),并将其传递到下一个操作中。我应该在 Store 中分发包含 ID 的下一个动作,而不是在其他动作之后分发多个动作吗? 其他问题请参见这里 - Felix Hagspiel
最好的做法是使用相同的操作并在两个存储上进行监听,然后相应地进行更改。实际上,总有一种方法可以做到这一点。你只需要稍微调整一下你的代码。你可以使用以下方式进行分发:{data_for_store1: {...},data_for_store2:{...},action:'ADD_ITEM'},这样两个存储现在都可以使用相同的操作。这对你有帮助吗? - Bhargav Ponnapalli
这是我一开始正在做的事情,但是 action1 在 StoreA 中创建了一个新的 ID,我需要以某种方式将这个新创建的 ID 传递给 StoreB。是否可以通过修改调度程序来完成此操作,以便在分派后返回值? - Felix Hagspiel
由于数据模型的复杂性,不幸的是将它们合并到一个存储中是不可能的。从StoreA中触发其他操作是否是一个不好的建议呢?非常感谢您的快速帮助! :) - Felix Hagspiel
如果是这种情况,那么你应该从存储中触发该操作。虽然这不是一个好主意,但如果它能够工作,那就是最重要的。但是,请确保不要陷入无限循环,即Action->Dispatch->Store->Action。 - Bhargav Ponnapalli
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接