Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I'm still somewhat unclear on the point of the Dispatcher and Actions and they simply feel like needless indirection to me.

For instance, in the flux-chat app within the linked repo, the MessageComposer component calls `ChatMessageActionCreators.createMessage(text);` when the user press the enter key to submit a message.

To find out how that ends up affecting the application, you need to jump around more than a couple of directories to find out how it's all wired up.

I just cut out the middlemen and directly interfaced my Stores from my components. My Store then emits a change event as usual and other components that are subscribed to the change event than refetch their state. That part of Flux makes perfect sense to me. The need for Dispatchers and Actions don't.

To be fair, I didn't start looking into Flux until my app starting growing large enough that I started feeling the pain of my lack of architecture. The Stores and the event emitter solved my immediate problems. Perhaps if my app grows even larger, the Dispatcher may come in handy.



Came to write the exact same thing. I chatted with some other people on the react irc channel about it and interfacing with stores directly seems to be pretty common. It's been working well for me so far in the smallish app I'm writing now.

To expand a little, I have trouble identifying what the difference between these two flows are;

    (something) -> store method -> change event
    (something) -> "action" -> store method -> change event
Feels like actions on the dispatcher are an unnecessary level of indirection when I have to know that I'm calling a store method under the hood just by virtue of knowing the action to call. I understand batching events and things like that, but manually wiring seems like a really boilerplate heavy solution to the problem.

Now that I'm writing this, I can kind of see the usefulness in making reusable components that can interact with stores. I guess I just felt like reusable components would never interacted with stores (as that's handled by controller-views which are pretty much application specific). But even then they need access to the dispatcher, and if you can inject that dependency then you can inject the store itself...

Sorry for the stream of consciousness, it's my lunch break...


Probably more reasons, but a few off the top of my head: 1) Multiple stores can respond to a single action 2) Single action listener may call multiple store methods 2) Can reduce the number of places a store is modified from


Another benefit is that the Dispatcher handles all the ordering of updates for you. If you have complex relationships between your stores or even if they just must handle updates in a certain order, by sending all updates through the dispatcher you can also force a partial ordering of store updates through dispatcher.waitFor(<other store>)


You can imagine that a key command, a click on a button, or even a command originated from a remote control that arrives proxied over a WebSocket - all of these could create the same Action. Each Store shouldn't care, or have any interest in, what component created that Action. And you should be able to add new Stores and new interaction types at runtime, as if (in music production) you were plugging in a plug-and-play MIDI keyboard and simultaneously adding a new audio plugin that reacts to any MIDI input. The Dispatcher removes any dependencies between these components; everything just needs to know about the Dispatcher.


Just trying to understand here:

What's the practical difference between the dependency on knowing the right action to call to the dispatcher vs. the dependency on calling the Singleton Store method?


I haven't used flux yet, but I'm assuming a single action might call on multiple stores? Eliminates having to handle that in a dependency


But even that action will have to manage the dependencies on these multiple stores, doesn't it? Whether it's called an Action or associated with a Store, does it make a practical difference?


You are absolutely right that actions are just another level of abstraction that come with their own pain, and if the pain they bring does not relieve an even greater pain of not having them then there is no reason to introduce them yet.

In our app, we started feeling the growing pain of a laissez faire approach to internal comms. For us, a user interaction can generate multiple logical state changes in the app, and several related interactions can cause similar/identical changes to take place. So for us, "User Interaction->App Change" is a many-to-many relationship, and Actions help us to wire them together really well. Couple examples -

1. Opening a modal with the detail view of the item. This can happen in several ways (a user click, onload, keyboard shortcut, app event), and it involves multiple steps (ui cleanup, fetching of more info, etc). Having an actions allow us to guarantee that when we want X to happen in the app, all necessary steps will be taken regardless of what causes X or in how many places.

2. Capturing analytics. We log all key interactions for internal analysis, and some events simply do not belong in the store/ViewController/component, so we capture in within the relevant Action. Low-level events are captured within components (e.g. did they press the 'save' button or hit enter), while others are app-level actions (e.g. 'view details') and are captured within Actions. Bonus - as per the point #1 for us multiple user interactions can cause similar app changes, but by also capturing the event within Actions we can easily track all triggers - e.g. was the 'view details' caused by a clicking on a link, using a shortcut, or another app-level change.

3. Refactoring. Most of the app UI is aware of only two things - Actions and (to a lesser extent) getState() of relevant stores. This means that as long as we keep the public interfaces of those two unchanged, we can refactor or even change the implementation as much as we need. Just last week we swapped the inhouse filtering/sorting implementation a for new one based on Crossfilter which caused a comprehensive rejigging of the stores' behaviours and methods, and because we kept the same public contract it had zero impact on the UI (besides a noticeable speed improvement).

Pardon the flawed comparison, but for us actions are useful in a similar way that interfaces or MVC controllers are useful - as long as you keep them lightweight and semantic, they provide predictable and reliable endpoints for the app regardless of what turmoil happens behind the scenes.


I'd be very interested in seeing some Crossfilter-based filtering store code. I've been working on a business application that needs to do quite a bit of filtering and hierarchical rollups, and I'd really like to start using Crossfilter for it so we can chuck the much more limited tool I whipped up when we started the project and get that speed boost you mention.

We're also starting to see a lot of the many-to-many relationships in actions you mentioned, which convinces me we need to work towards more of a Flux architecture (it wasn't out yet when we started this lo those many months ago).


I'd be happy to have a chat over Skype and share what we've done - just drop me a line to [redacted]


Because I didn't want to add so many layers at once, I just implemented Stores -> ControllerView -> View -> direct Store call.

As far as my understanding goes that should be fine for most use-cases. The only reason that really requires a Dispatcher would be synchronization of the incoming Store mutations.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: