Think of a messaging application developed using Angular, which may have multiple views that represent the current state of users messages like an icon on the top header bar that shows number of new messages arrived, and a messages page where we have a teaser view that displays recent messages with the name of its sender and multiple chat tabs on the bottom of the screen for ongoing conversations. The top header bar and these chat tabs are visible on all the other pages available on the application to keep the conversation on all the time.
All these are independent views that are needed to be in sync. And what is important here is that they do not have a parent-child relationship. So this top header section is not a parent or child of any other view here, as it is visible all the time irrespective of the page user is visiting. In case of a parent-child relationship, passing data would be easy. It would simply use the input properties of the child components to pass the data on the downline components. But as these views are independent of each other, if we want to keep all of them in sync, we have to put more efforts and do extra work.
For such a situation, the very common solution is to use events, but sooner or later that will turn into a complicated event network. In a large codebase, we have events published all over the places and then, to track them, to see what is going on and what happens to the applications state we have to jump all over the code. The biggest problem with this solution is that the data can be updated in an unpredictable way. When there is a bug we have to jump all over the code to figure out how the data is flowing and how the application state is updated on multiple places. so it is unpredictable. As soon as we add a new feature, it becomes another challenge. Because once again impact of this new feature on the application state is unknown to us. If the new feature is using and updating the same piece of data that is in different places, that needs to be kept in sync. Again we have to do a lot of hard work to maintain all this correctly.
What’s the solution???
Facebook had a similar problem back in 2014, and as a solution, the Facebook development team introduced the Flux architecture.
So… what is Redux?
Without the Redux in a typical Angular application, each component maintains the state and the logic behind a view. So each component has their own state. These components may communicate with each other and update each other’s state. This model aligns perfectly with the encapsulation principle of object-oriented programming structure. But, it can be a problem when we have multiple views that are working with the same piece of data and do not have a parent-child relationship. In this situation, we often have multiple copies of the same data that are independent of each other. So the state of the application as a whole becomes extremely complex and confusing and whenever some model is updated, we need to do some extra work to keep the other views of the application in sync.
What other benefits Redux has for us?
- Redux makes it easier to unit test an application in a much easier way and without using mocks or any other tricks that can make testing complex and error-prone both.
- As Redux is heavily based on functional programming, one can very easily go with Test-driven development (TDD).
- Redux development tool is awesome. It is a browser extension that you can add to Chrome, Firefox, and other browsers. It makes it incredibly easy to debug our application by allowing to inspect the application state very easily.
- With Redux it is incredibly easy to implement features like Undo and Redo. So if you need these functions in your application, Redux makes your life much easier.
When is it right to start using Redux?
Well, all these fancy features come with a cost. Just like any other architectural patterns developer has to write some more code and in your application, you will find some more moving parts. So use Redux only if you are building a medium to large single page application with complex fields with complex data flows.
If you are building a simple application with a simple data flow, you don’t necessarily need Redux. And in fact, Redux can add extra unnecessary complexity to your application.When-is-it-right-to-start-using-Redux
When one should start thinking of Redux as a solution?
- When you see multiple independent copies of the same data on multiple places in your application.
- In the application, there are multiple views that need to work with the same data and needed to be in sync.
- If your application users can work on the same piece of data, so data can be changed by one user and at the same time any other user can change the same data. other words, data can be updated by multiple users.
- Data can be updated by multiple actors like user actions and at the same time, it may arrive from the server.
If you have these or similar scenarios in your application, you should probably use Redux to get potential benefit from it.
Also, when building a new potentially large application, you do not need to start using Redux from the very first day. The development can always be started simple and as the application grows then refactoring can be done in existing components and if said similar scenarios are visible then use Redux to manage the application state in a predictable and deterministic way. In this way, your life will be much easier, hassle-free and Relaxed.