【问题标题】:Why is Dispatcher launching unnecessary events on Flux?为什么 Dispatcher 在 Flux 上启动不必要的事件?
【发布时间】:2016-01-19 11:43:30
【问题描述】:

我有一个包含以下组件的 React/Flux 应用程序:

  • header.js
  • subnav-area.js
  • feed-area.js

我也有相应的店铺:

  • navbar-store.js(标题)
  • subnav-store.js
  • feed-store.js

...和行动:

  • navbar-actions.js(标题)
  • subnav-actions.js
  • feed-actions.js

按下子导航上的按钮时,提要和子导航都应更新,设置正确的提要类型并突出显示活动的子导航元素。我成功实现了这个目标,但我也多次启动了 onChange 事件,也使用 header.js 组件,即使它不应该受到操作的影响。

在动作中我这样调用调度员:

AppDispathcer.handleViewAction({

  actionType: AppConstants.SUBNAV_SET_ACTIVE,
  _id: subnavItemId
})

...当然,取决于目的。我的调度员看起来像这样:

handleViewAction: 函数(动作){

this.dispatch({ 来源:'VIEW_ACTION', 行动:行动 }) }

在商店里我有这样的东西来处理调度员:

dispatcherIndex: AppDispatcher.register(function(payload) {

  var action = payload.action;

  switch(action.actionType) {

    case AppConstants.FILTER_SET_CAT:

        FeedStore.selectVisibleFeedItems();
      break;

    case AppConstants.FEED_SHOW_MORE:

        FeedStore.showMoreItems(filterCatName);
      break;
  }

  FeedStore.emitChange();

  return true;
})

所有组件都有以下功能(但监听器名称不同):

  componentWillMount:function(){

    FeedStore.addFeedListener(this._onChange, 'feed-area.js');
  },

  componentWillUnmount:function() {

    FeedStore.removeFeedListener(this._onChange)
  },

  _onChange: function(){

    this.setState(getVisibleFeedItems())
  },

现在,当所需的操作发生时,_onChange 会在以下所有组件上启动:标题、子导航区域和提要区域组件。

我从哪里开始寻找错误?我不完全理解调度程序是如何工作的,我应该以某种方式分离处理视图的功能吗?我以为 Flux 会以某种方式监听商店并根据它更新视图,现在它似乎在监听其他内容,我真的不明白是什么。

【问题讨论】:

    标签: javascript node.js reactjs reactjs-flux flux


    【解决方案1】:

    我将开始描述一般想法的示例,然后继续介绍如何调试。

    假设我有一个购物车和一个物品Component。

    每当add 事件从Item 组件触发时,它应该触发Action,比如说,向您的服务器发出AJAX 请求,然后调度一个名为CART_ITEM_ADDED 的事件(在您的情况下,我猜你会做Dispatcher.handleViewAction('CART_ITEM_ADDED')。调度程序会告诉它的订阅者收到了一个事件,每个订阅者都会查看它是否对该事件感兴趣。对CART_ITEM_ADDED事件感兴趣的订阅者然后可以更新@ 987654333@ 并告诉它从服务器重新获取购物车。一旦完成,商店会触发一个事件,说不超过“好的。我已经改变了”,然后订阅CartStore 的每个视图都有责任从 CartStore 重新获取他们需要的信息。

    开始调试:

    在我的调度程序中,当运行调试模式时,我总是打印正在调度的事件。因此,在您的handleViewAction 中,您可以使用console.log('[DISPATCH]', action);,它可以让您清楚地了解正在调度哪些事件以及以什么顺序。

    当您的商店发出更改事件时,您也可以这样做。记录下来,你就会知道发生了什么。

    我很难在没有更多内容的情况下告诉您确切的问题,但通常很容易混淆和混合调度程序回调和动作创建器的常量。也许您在某个地方的错误位置监听了错误的事件?

    我也看到你在做类似的事情

    FeedStore.addFeedListener(this._onChange, 'feed-area.js');
    

    你有什么理由不使用通用的addEventListener?

    您应该告诉商店的只是“嘿!只要有事情发生就运行这个函数,好吗?”通过FeedStore.addEventListener(this._onChange);

    这个答案比我预期的要长,我希望它有帮助,如果没有,请随时提问!

    【讨论】:

    • 我快速破解了这个小伪代码。也许这有助于理解这个概念:pastebin.com/5Zpi9zRJ
    • @JaakkoKarhu:我没有 100% 关注,但我想我明白了。只有在 FeedStore 发生实际变化时,您才应该启动 FeedStore.emitChange();。您的调度员回调可能如下所示:pastebin.com/RMSEphNY 我会尽力提供帮助,直到您解决问题,所以请继续提供反馈,我们会解决这个问题!
    • @JaakkoKarhu:我从一些现有的 jsfiddle 开始并重写了它,以便您可以看到基本概念的实际应用:jsfiddle.net/rhs1um2c/2 希望对您有所帮助!
    • 在此回复:jsfiddle.net/8kLod1xa/4 调度程序回调确定如何处理通过调度程序发送的事件。如果它对某些东西感兴趣,它将用数据更新商店。一旦商店中的某些内容发生更改,该商店应发出更改事件(.emitChange())以通知组件。所以 Store 应该只在 .emitChange() 已经更新了新数据的情况下执行。然后听那个商店的组件就会知道他们应该调用类似FeedStore.getFeed()的东西我不确定我的cmets是否足够。但请继续询问,我会尽力提供帮助!
    • 以下是对您的 pastebin 的一些回复:pastebin.com/x0VBwFiJ 它解释了为什么 addChangeListener 不适合您!
    猜你喜欢
    • 2021-08-03
    • 2014-07-12
    • 2015-01-27
    • 1970-01-01
    • 2016-01-08
    • 2016-02-06
    • 2016-06-25
    • 1970-01-01
    • 2015-09-10
    相关资源
    最近更新 更多