IntroIn this series we've learned about the benefits of a Component based architecture and we have seen how it differs from the traditional MVC architecture.
A Component based architecture is a Tree of Components in which each Component takes care of a part of the UI of an application. We saw that managing state for a Tree of Components can be difficult because the state lives in various locations.
We also saw that communication between Components can be difficult because a Component can only talk with his children or with his parents. Components that need to talks to their siblings or nephews require channels to be opened through their parents.
We learned about unidirectional data flows and about observables, two ways to reduce the complexity of a Component based architecture.
This week I want to share my personal opinions and experiences about Components, Redux, Cycle.js, Observables etc etc.
MVC vs ComponentsPersonally I prefer Components. I've been exploring Components based architectures for quite some time now and I've come to the conclusion that I find that it fits better when building UI's.
Whenever I used MVC I always had a feeling things did not quite fit. The main reason for this is that there was supposed to be a loose coupling between the controller and the view. The reality however was that they were very tightly coupled.
Whenever the controller changed the view had to be updated as well. When you re-factor the name of an 'event' the view had to be updated to use the new name as well. If the view was changed significantly it almost always meant that the data structure in the controller had to change as well to make it easier for the view.
So say that the Controller and View were loosely coupled in MVC was simply disingenuous. With Components I feel that this charade has finally come to an end.
A Component marries the 'controller' and 'view' very tightly together into one single concept. Finally the way I wrote the code was reflected in the architecture that I used.
With MVC I always feel that I'm building something simple out of complex pieces. With Components I feel that I'm building something complex made out of simple pieces.
For example in MVC I would often write code for relatively simple screens such as a list where you can traverse through some model via pagination, with edit, delete and view functionality. The idea is relatively simple, but the code quickly became complex. The controller would get bloated, the view's would get huge.
When another view was introduced which was also a list the code would often end up duplicated. The correct thing to do is to make the list a Component, but you where not always guided to this solution. Maybe I can write some 'mixins' for my controller, or write a partial for my views. It reduces the total lines of code, but is a very poor layer of abstraction.
When you go full Component it is clear that the solution is a generic list component. The code used to build the application specific UI are Components, the code for re-usable widgets are also Components. This means that you have one abstraction for both use cases, which makes Components in my opinion conceptually easier to understand.
Easier to re-use
Since Components are isolated and have very explicit communication semantics, they are ideally suited for re-use. Of course in the traditional MVC this was also the case for the widgets that we re-used, which where sort of Proto-Components.
The difference was that when you decided that a widget was re-usable as a Component you would have to extract parts out of the View. With Components you are already building isolated widgets.
Is it really that different?
In some ways a Component architecture is just a special variant of the MVC architecture. I'd like to view Components as a group of very tiny MVC applications which work together to tackle a bigger
This means that we do not have to learn everything all over again. We only need to get into the Component mindset.
Managing State and EventsSo if you make the plunge and go for a Component based architecture you will soon run into the limitations. Namely that the state will be stored in multiple different Components, and that Components will start developing multiple lines of communication to each other.
We've seen that Redux (unidirectional data flow) and Reactive Programming can reduce these problems. So which one do you pick.
Rx.js vs Redux
Redux is strong at managing you state for your entire application. It is an architecture for how to deal with state. It makes sure that your applications state is not shattered through out the Component. It allows communication between Components through manipulation of commonly shared state.
Rx.js is used for asynchronous programming it makes it easier to deal with events. What is also beautiful is that the Components are Reactive, they themselves define to which events they respond from inside the Component itself, and not through being manipulated via some external call. It allows communication because one Component can generate events to which another Component can listen to, without them knowing each other explicitly.
Rx.js and Redux do not exclude each other you can use them at the same time if you want to. So it actually is not a fight.
What about Cycle.js
Cycle.js is a really cool project which shows how great an application which uses Observables can be. The downsides are that the project doesn't have the developer tools that Redux does provide.
Also I find that it is very difficult do jump into the "everything is a stream" mentality. Getting new developers on board is in my opinion more difficult.
Also Cycle.js is a relatively smaller project than lets say React, Ember or Angular. This means Cycle.js doesn't have the big community that the others have, so it is harder to ask for help.
But who knows things may be different in a couple of years.
RecommendationsSo what do I recommend?
Personally I recommend using Redux first and Rx.JS later. By using Redux you get a pretty solid way to deal with state. This combined with the developer tools that are available for Redux provides a great developer experience. Redux is also relatively easy to explain to developers, developers new to Redux should become productive quickly.
When Components start relying heavily on asynchronous events, Rx.js might be a good fit to use for some Components, such as an autocomplete search box. At the end of a Stream you can then dispatch back to the Redux store to update the state.
In theory you could use Rx.js to create your own Redux like implementation. An Angular 2.0 library called: ngrx/store does just this. It proves that Rx.js can be used to implement Redux like stores. Since 42 B.V. is an Angular shop I'm going to investigate this approach.