Today, as I find these two technologies similar in some ways, I decided to compare them.
TL;DR: as Angular 2 is strictly opinionated and using things like ES6 syntax is advised by the authors, I will compare it with the most modern way of using React (e.g. combined with Babel for ES6 syntax and using JSX syntax for templates). In my comparison I will try to show the main similarities and differences leaving the decision on which one is better to you.
Good question! Many of you may say: “ReactJS is just a library and Angular 2 is a comprehensive framework! You can’t compare the two…”. I completely agree. My thinking was that if we are stubborn and, in spite of that, we still want to do the comparison, we have two choices: we can either take React and compare all its elements to appropriate elements of Angular2 or we can compare Angular 2 as a framework with the whole ReactJS “ecosystem” - when you create a React application you will most likely use such libraries as react-router, Redux, Immutable, etc… Well, I prefer the second option and will try to follow this path today.
Ok, let’s start the comparison with the most important and obvious part. Both ReactJS and Angular 2 are based on the same concept: build an app using small pieces called
components. Here’s how it’s usually done in ReactJS:
Now, let’s see a very similar component in Angular 2:
The main difference here is that in React we have to extend a base
Component object and in Angular 2 we have to use a decorator
@Component. This is the thing which might make creating the component more difficult in Angular 2. In React you just have to create a component and use it in other components as if it was an HTML element (thanks to JSX syntax - again, I will write about it later). In contrast, in Angular 2 you have to make a placeholder in an HTML template and then inform the component where it should be injected (using the
selector property of the decorator).
Another difference we can see here is that in Angular we use templates as separate files as it was in the previous version of the framework (we can also declare a template as a string just like, for example, in
Ok, now that we know something about components, we can talk more about templates in both technologies. As I wrote before, in React we declare templates inline in the
JSX syntax allows you to assemble component’s template from the other components and HTML elements in a XML-like way. The effect is very similar to a pure HTML template. The JSX template becomes a part of React’s Virtual DOM which is the best element in the library - when React starts rendering components in the browser, it takes all components first and builds an in-memory (virtual) representation of the DOM tree. Then, on top of it, React reconcile a real DOM tree and sends it to the screen. Thanks to that reacting to any UI change is very efficient because every time React re-renders the component it has to compare the Virtual DOM with the real one and change only these parts of the real DOM which are different.
On the contrary, in Angular 2 we still have templates as separate HTML files. These templates are rendered in a regular way and every change in the UI is made just by the DOM manipulations.
When we talk about DOM manipulations, we can’t forget about data binding - this is also different. In Angular 2 we still have a two-way data binding which you can remember from the previous versions of the framework. This means that our templates may look like in the example below:
So first, please have a look at line number 2. The
message is a component object’s property. Its value is bound to the
div element using double curly braces - this way we can achieve a one-way data binding which means that in this place we can only see the actual value of the property. In line number 4 we have the same property bound to the
input element using two-way data binding (thanks to the
[(ngModel)] attribute) - when we change the value of the
input the value of the property will be changed too. This is the power of the two-way data binding.
The main disadvantage of this approach is that we end up with a template full of strange custom attributes which looks even more weird than in the previous versions of the Angular framework.
Ok, so how is it done in React? Well, first of all, we don’t have two-way data binding here - we only show the actual state of the model. Let’s conjure up the component’s render method from the first example:
As you can see in line number 4, to bind the data we use single curly braces. You may also notice that we bind to the
message property of the
state object. This is important because every time the value of the property changes (we should always do this using the
setState method of the base component class), React re-invokes the render method of the component. This causes a change of the Virtual DOM stored in the memory which is then compared to the real DOM and, if it differs, the change is applied.
Sounds very simple. And it is. The main disadvantage of this approach is that nothing happens “automagically” here - we have to write more code than in two-way data binding because we have to change the state manually.
Both ReactJS and Angular 2 support the modern syntax of ES6/ES2015 - as I wrote before, a component in both technologies is just a class. But there is a difference - with ReactJS we usually use Babel to transpile ES6/ES2015 code into its ES5 counterpart.
This is one of those things which is a part of Angular 2 but in the React world is covered by an external library. The most popular one is react-router so I will rely on that one in my comparison.
Let’s start from the react-router. Here’s how to declare routes using this library:
Basically the code above is usually added to the entry script of the React application. As you can see, routes are configured using
Route components. Every route combines the URL of the currently displayed page with the appropriate component. We should usually consider every component passed to the route as a single subpage - it will be added to the element with
id="app" (please see the second parameter of the
And how does it look like in the Angular 2 application? Please see the sample routing configuration:
Well… Decorators again… We just add the
RouteConfig decorator before the main application component. Here we can declare the path to recognise and inform the router system which component should be displayed. And at what place the component will appear? In previous versions of Angular we had an attribute
data-ng-view. Now we have a custom component:
You have to add the above code into the template of the main application component - the component which matches the appropriate path will be shown here.
As you can see, it generally looks pretty simple in both technologies and both solutions works well enough.
As React is just a library it does not provide any architecture itself. But Facebook developers, who are the creators of this library, advise to use a Flux architecture. It provides a unidirectional data flow. An action which contains its type, and eventually new data, is sent to the dispatcher. The dispatcher invokes callbacks registered in the stores that match the type of action (this way it dispatches the action to all stores). Whenever the store callback is invoked, it sends a change event to inform the view. The view may change its state according to these events and re-render itself. The view can also invoke other actions, e.g. when a user interacts with it and the flow starts again.
The Angular framework was initially an implementation of the MVC pattern. In the upcoming version, the architecture is based on components. Actually it’s simple - the component and the template share data using two-way data binding and the component also uses services directly to deal with cross-cutting concerns like accessing data, logging, configuration etc. Everything which provides any data or information may be a service. In Angular 2 we also have mechanisms which should help us to work this way such as dependency injection.
As you can see, it seems it is not strongly opinionated - they gave us components and services and basically that’s it… Fortunately we can use another architecture if we like. For example in this article you can see how to use Flux architecture (to be precise they use Redux) with Angular 2, so… you can do such things with this framework.
Phew… that’s all. I haven’t written such a long article for a long time… and I hope it was worth it. I believe there are more parts of these two technologies which can be compared but I’ve tried to focus on, in my opinion, the most important ones. I have really tried not to add my personal opinion here because I know that choosing which technology is better is a very controversial subject these days… So, every time you have to make the choice, be pragmatic, consider all your needs and preferences and make your own independent decision! Both are really great technologies and both will probably be applicable to your project.
Similar comparisons and other useful links: