{"action":"created","issue":{"url":"https://api.github.com/repos/BinaryMuse/fluxxor/issues/92","labels_url":"https://api.github.com/repos/BinaryMuse/fluxxor/issues/92/labels{/name}","comments_url":"https://api.github.com/repos/BinaryMuse/fluxxor/issues/92/comments","events_url":"https://api.github.com/repos/BinaryMuse/fluxxor/issues/92/events","html_url":"https://github.com/BinaryMuse/fluxxor/issues/92","id":54028931,"number":92,"title":"Trigger `this.emit( 'change' );` after dispatch ends","user":{"login":"mjangda","id":86105,"avatar_url":"https://avatars.githubusercontent.com/u/86105?v=3","gravatar_id":"","url":"https://api.github.com/users/mjangda","html_url":"https://github.com/mjangda","followers_url":"https://api.github.com/users/mjangda/followers","following_url":"https://api.github.com/users/mjangda/following{/other_user}","gists_url":"https://api.github.com/users/mjangda/gists{/gist_id}","starred_url":"https://api.github.com/users/mjangda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mjangda/subscriptions","organizations_url":"https://api.github.com/users/mjangda/orgs","repos_url":"https://api.github.com/users/mjangda/repos","events_url":"https://api.github.com/users/mjangda/events{/privacy}","received_events_url":"https://api.github.com/users/mjangda/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-01-12T08:13:10Z","updated_at":"2015-02-01T06:01:33Z","closed_at":null,"body":"I'm using Fluxxor + rackt/react-router and running into the \"Cannot dispatch an action (...) while another action (...) is being dispatched\" error.\r\n\r\nHere's what I'm doing:\r\n\r\n- A Login route/component displays a login form\r\n- onSubmit triggers the \"login\" action creator.\r\n- The \"login\" action creator interacts (async) with our API to validate the submission. When the call completes, dispatch the \"LOGIN_SUCCESS\" action (assume no failures for simplicity)\r\n- AuthStore is listening for this action and updates its data and triggers an `this.emit( 'change' );`\r\n- The Login route/component is using `StoreWatchMixin( 'AuthStore' )` to listen for updates and uses react-router to `transitionTo( 'dashboard' )`\r\n- During its setup, the \"dashboard\" route/component triggers an action.\r\n- The \"Cannot dispatch an action...\" error is thrown.\r\n\r\nThe problem is that the `emit` call triggers the transition and results in the \"dashboard\" component set up while the dispatcher thinks that the \"LOGIN_SUCCESS\" action is still being fired.\r\n\r\nIs there a way to defer the `emit` call to after the action dispatch is complete? Or should I be thinking of another approach to this? (I could do a `setTimeout` but that feels fragile.)"},"comment":{"url":"https://api.github.com/repos/BinaryMuse/fluxxor/issues/comments/72353080","html_url":"https://github.com/BinaryMuse/fluxxor/issues/92#issuecomment-72353080","issue_url":"https://api.github.com/repos/BinaryMuse/fluxxor/issues/92","id":72353080,"user":{"login":"BinaryMuse","id":189606,"avatar_url":"https://avatars.githubusercontent.com/u/189606?v=3","gravatar_id":"","url":"https://api.github.com/users/BinaryMuse","html_url":"https://github.com/BinaryMuse","followers_url":"https://api.github.com/users/BinaryMuse/followers","following_url":"https://api.github.com/users/BinaryMuse/following{/other_user}","gists_url":"https://api.github.com/users/BinaryMuse/gists{/gist_id}","starred_url":"https://api.github.com/users/BinaryMuse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BinaryMuse/subscriptions","organizations_url":"https://api.github.com/users/BinaryMuse/orgs","repos_url":"https://api.github.com/users/BinaryMuse/repos","events_url":"https://api.github.com/users/BinaryMuse/events{/privacy}","received_events_url":"https://api.github.com/users/BinaryMuse/received_events","type":"User","site_admin":false},"created_at":"2015-02-01T06:01:33Z","updated_at":"2015-02-01T06:01:33Z","body":"There are a few things at play here.\r\n\r\nFirst, not allowing cascading dispatches isn't a technical limitation; the decision to add that restriction was purposeful, based on the flux design pattern, and is even listed in the \"Key Properties\" on the \"What is Flux\" page. The restriction helps promote good data flow design by forcing you to think about your actions in terms of domain concepts rather than rote instructions your stores are following. Long story short, I'm not in favor of simply removing the cascading dispatch restriction and calling it a day.\r\n\r\nThe problem, as mentioned above, is that this restriction causes exceptions when one action causes a new component to be mounted, and that new component immediately fires another action in `componentDid/WillMount`. For what it's worth, I'm starting to feel like this is an antipattern. It's just another form of cascading dispatches; a button click dispatches ActionA, which causes a new component to mount, and that component's `willMount` dispatches ActionB, which causes a new component to mount, which dispatches ActionC... all of the sudden your application state is wildly different because of all the cascading actions, and this is the hard-to-debug scenario that the only-one-dispatch-at-a-time rule is supposed to solve. In fact, it's probably even *more* insidious because the dispatch ordering is implicitly defined by the order of new components mounting throughout the application.\r\n\r\nThat said, I also understand that this is a common pattern (and even implicitly recommend it in one of the examples on the site), so I think I'd like to support it if we can. The real problem here, and what makes it hard to debug, is that React renders immediately *sometimes* but not others. Take the following example ([see it working at this JSFiddle](http://jsfiddle.net/BinaryMuse/map5vf94/)):\r\n\r\n```javascript\r\nvar App = React.createClass({\r\n  render: function() {\r\n    console.log(\"Rendering\");\r\n    return (\r\n      <div>\r\n        <p>Value: {this.props.value}</p>\r\n        <button onClick={this.sync}>Increment Synchronously</button>\r\n        <button onClick={this.async}>Increment Asynchronously</button>\r\n        <p>\r\n          When incrementing synchronously, rendering happens on the same tick,\r\n          but after the increment function has fully finished. When incrementing\r\n          asynchronously, rendering happens immediately on the same tick,\r\n          before the increment function has finised.\r\n        </p>\r\n      </div>\r\n    );\r\n  },\r\n    \r\n  sync: function() {\r\n    this.props.increment();\r\n  },\r\n  \r\n  async: function() {\r\n    setTimeout(function() {\r\n      this.props.increment();\r\n    }.bind(this));\r\n  }\r\n});\r\n\r\nvar value = 0;\r\n\r\nvar increment = function() {\r\n  console.group(\"Increment\");\r\n  setTimeout(function() {\r\n    console.log(\"Next tick\");\r\n    console.groupEnd(\"Increment\");\r\n  });\r\n\r\n  console.log(\"Starting increment\");\r\n  value++;\r\n  render();\r\n  console.log(\"Ended increment\");\r\n};\r\n\r\nvar render = function() {\r\n  React.render(<App value={value} increment={increment} />, document.body);\r\n};\r\n\r\nrender();\r\n```\r\n\r\nWhen you click the left button, the console logging ordering is:\r\n\r\n```\r\nStarting increment\r\nEnded increment\r\nRendering\r\nNext tick\r\n```\r\n\r\nHowever, clicking the right button, the order is:\r\n\r\n```\r\nStarting increment\r\nRendering\r\nEnded increment\r\nNext tick\r\n```\r\n\r\nThis is the problem, I think—state changes caused by event handlers allow the handlers to fully process before React re-renders, allowing the dispatch loop to finish. However, actions that are dispatched asynchronously cause an re-render immediately, and Fluxxor flows since the dispatch loop hasn't completed.\r\n\r\nSo far, I've been unable to tell if this is on purpose or just a bug or side effect of the implementation used in React. I'll keep digging."}}