The official docs say that it gives you the control over how data flows throughout your app. I didn't get this. How is this principle violated if I decide to support two-way data binding and other MVC concepts?


It's about managing complexity as you add features. In the end, a unidirectional data flow, especially combined with a single store and single state tree (redux, socrates and similar) which distill from the flux pattern, mean that changes to state happen in a consistent manner, and that actions/events are also dispatched consistently.

In this way, there is more cognitive overhead getting started in a new project, because the pattern breaks typical binding on components and separates out your control flow away from controllers and towards reducers. In the end, as you add features, new data, new containers/views/components/controls, you don't add much new complexity, and the logic is easier to manage.

It's hard to get into this mindset when you start a project, and the "community standards" are evolving... but it's easy to see how this works better in larger applications. In a simple TODO app, not so much, but in very large line of business apps, absolutely.

Anecdotal example, At work, I'm currently supporting three applications. One is an angular 1.x line of business application that is customer facing, it is very component/service centered and making changes to the workflow are very hard, to say the least... Another is a react+redux proof of concept for the prior application. The proof of concept handles roughly half the workflow of the original app (designed for the portion of workflow), but the codebase covering that workflow is a fraction of the size, and a lot of the larger complexity is gone and significantly easier to follow. The third is a new application using Angular 2, but it's going to use a single store/state tree. It's in Angular 2 (political reasons) as handed down, and unidirectional workflow, single-state based because it's proven itself out to reduce total complexity with additional features.

A bit of advice, divide up your structure (actions, reducers, controls, components, views, containers) based on feature, not based on types at a higher level. When you need functionality that is a cross-cutting concern, expose hooks via each feature's top level index, and use that for bridging the gaps.

(4 answers) Take me to the question