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).
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.