React vs Angular - A Popular JavaScript Library and a Powerful JavaScript Framework

A ReactJS vs AngularJS comparison is a popular topic. React and Angular (we won’t use the JS ending all the time throughout the article) are both advanced, widely adopted JavaScript (JS) technologies that we use to create interactive single-page applications (SPAs). The number of JS tools for fast single-page application development is constantly growing, making the choice of which technology to rely on more challenging for us as web developers.

React and Angular comparison chart

Both React and Angular are currently used by many business, news, and travel companies in the USA, the UK, Canada, France, Germany, Australia, and other countries. AngularJS has been included in virtually every list of top 10 JavaScript frameworks since its release in 2009. This Model–View–Controller framework has become extremely popular among web developers. ReactJS is even more widely used by JavaScript programmers, although it’s actually a library, not a framework: the React library only has a View, but lacks Model and Controller components. So how did React became so popular? And how can we reasonably compare a framework (AngularJS) with a library (ReactJS)?

First, take a look at the React vs Angular comparison in the table below.

Technology AngularJS ReactJS

Developer

Google

Facebook

Technology type

Full-fledged MVC framework written in JavaScript

JavaScript library
(View in MVC; requires Flux to implement architecture)

Concept

Brings JavaScript into HTML
Works with the real DOM
Client-side rendering

Brings HTML into JavaScript
Works with the virtual DOM
Server-side rendering

Data binding

Two-way data binding

One-way data binding

Dependencies

Manages dependencies automatically

Requires additional tools to manage dependencies

Language

JavaScript + HTML

JavaScript + JSX

Last version

AngularJS 1.6.0 RC2

React 15

Suits best

Best for SPAs that update single view at a time

Best for SPAs that update many views at a time

This is only an short overview of the difference between ReactJS and AngularJS. We'll discuss Angular and React in greater detail in the following sections.

React vs Angular Comparison

The main differences between AngularJS (the framework) and ReactJS (the library) are in the following aspects: componentization, data binding, performance, dependency resolution, directives, and templating. Let’s look at each of these aspects separately.

Componentization

AngularJS

AngularJS has a very complex and fixed structure because it's based on the three layers — Model, View, and Controller — typical of single-page applications. An object $scope in AngularJS is responsible for the Model part, which is initialized by the Controller and then transformed into HTML to create the View for the user. Angular provides many standard services, factories, controllers, directives, and other components that will take some time for a JavaScript developer to master initially.

With AngularJS we break the application code into several files. For example, when we create a reusable component with our own directive, controller, and template, we must describe each chunk of code in a separate file. Once we describe our directive, we then add a link to our template in the directive to couple these parts. AngularJS directives represent the template logic for your application. The template is HTML extended with Angular directives, generally written as tags or attributes. We also add controllers to provide our models with necessary $scope or context. Controllers are written in separate files as well. When we modularize our application in such a way, we can reuse our template or component in a different part of the website.

ReactJS

Facebook, the creator of ReactJS, chose an architecture different from that of AngularJS and similar MVC frameworks. In short, there is no “correct" structure for applications built with ReactJS.

ReactJS is a large JavaScript library that helps us update the View for the user. But ReactJS still doesn't let us create applications on its own. The library lacks the model and controller layers. To fill in the gap, Facebook introduced Flux, which has numerous variants nowadays, to control the application workflow.

ReactJS provides a very simple and efficient way to build component trees. It boasts a functional programming style where component definitions are declarative. Composing your app from ReactJS components is like composing a JavaScript program from functions. Just look at the example below, taken from GitHub:

Code written in ReactJS is logically structured and readable thanks to the availability of components. The ReactJS library doesn’t demand that you write code in a certain way. They suggest that you use JSX (a special XML-like syntax) to create classes and templates, but it’s also possible to write plain JavaScript and HTML. This helps JavaScript developers adapt to React applications more easily, as there is no unusual syntax to learn. React offers a freedom that AngularJS doesn’t. But this freedom comes at the cost of additional time spent designing the structure of an application. Before we start a new project, we have to think about what instruments we are going to use. When you have to pick a tool from among 100 options to resolve a single task, this choice becomes cumbersome.

Data Binding

AngularJS

AngularJS connects Document Object Model (DOM) values to Model data through the Controller using two-way data binding. In short, if the user interacts with an <input> field and provides a new value to the app, then not only the View is updated, but the Model as well. Two-way data binding is beneficial for AngularJS as it helps us write less boilerplate code to create interactions between components (the View and the Model) in our application. We don't have to invent a method to track changes in the app and change our JavaScript code accordingly.

The drawback of Angular's two-way data binding approach is its negative impact on performance. Angular automatically creates a watcher for each binding. During development, we may come to a point when an app is packed with too many watchers for bound elements.

ReactJS

But what are the advantages of React over Angular with regards to data binding? React uses one-way data binding, meaning we are able to direct the flow of data only in one direction. Because of this, it’s always clear where the data was changed. It’s worth noting that two-way data binding was available in ReactJS before v15 thanks to ReactLink.

ReactJS Flux workflow

In order to implement a unidirectional data flow in React, Facebook created its own application architecture called Flux. Flux controls the flow of data to ReactJS components through one control point – the dispatcher. Flux's dispatcher receives an object (they call it an action) and transfers it to an appropriate store, which then updates itself. Once the update is finished, the View changes accordingly and sends a new action to the dispatcher. It's only possible to transfer an action to the store when it’s fully updated. With this concept, Flux improves the effectiveness of the code base. Based on our own experience we can say that Flux is great when you work with dynamically updated data.

The one-way data flow in ReactJS keeps complexity under control. It's much easier to debug self-contained components of large ReactJS applications than it is with similarly large AngularJS applications.

Performance

AngularJS

There are two things to take into consideration when we talk about Angular's performance. As we mentioned previously, Angular 1.x and higher relies on two-way data binding. This concept is based on “dirty checking," a mechanism that can make our AngularJS application laggy.

When we bind values in HTML with our model, Angular creates a watcher for each binding to track changes in the DOM. Once the View updates (becomes “dirty"), Angular compares the new value with the initial (bound) value and runs the $digest loop. The $digest loop then checks not only values that have actually changed, but also all others values that are tracked through watchers. This is why performance will decrease a lot if your application has too many watchers. This drawback is even more painful when several values (Views) are dependent on each other. Once Angular sees that the change of a value was triggered by another change of a different value, then it stops the current $digest cycle and runs it all over again.

The loop doesn't stop working until it checks all watchers and applies all necessary changes to both the View and the Model. In practice, we can bind an <input> field to different Views and Models. When the user enters new data into the field, the change may not be immediately visible. It’s better to avoid that.

Another shortcoming of the AngularJS framework is the way it works with the DOM. Unlike React, AngularJS applies changes in the real DOM in the browser. When the real DOM gets updated, the browser has to change many internal values to represent a new DOM. This also has a negative impact on application performance.

Poor performance is the main reason why Angular 2 supporters introduced the virtual Document Object Model rendered on the server and one-way data binding similarly to React. Still, Angular 2 offers two-way data binding as an option.

ReactJS

The creators of ReactJS introduced the concept of the virtual Document Object Model, which is regarded as one of the greatest advantages of ReactJS in comparison with mature frameworks, including AngularJS. How does the virtual DOM work? When our HTML document is loaded, ReactJS creates a lightweight DOM tree from JavaScript objects and saves it on the server. When the user, for instance, enters new data in the <input> field in the browser, React creates a new virtual DOM and then compares it with the previously saved DOM. The library finds dissimilarities between two object models in such a way and rebuilds the virtual DOM once again, but with new changed HTML. All this work is done on the server, which reduces load on the browser.

Now, instead of sending completely new HTML to the browser, React sends the HTML only for the changed element. This approach is much more efficient than what AngularJS offers.

As for one-way data binding, React doesn't use watchers to track changes in the real DOM. Overall, ReactJS makes it simpler to control application performance. But this doesn't mean we cannot create a fast application in AngularJS.

Resolving Dependencies

AngularJS

AngularJS uses a basic Object Oriented Programming (OOP) pattern called dependency injection, meaning we write dependencies in a separate file. It’s inconvenient to create a dependency directly in an object. In AngularJS, dependency injection is inherent to any standard functions that we declare for an Angular factory or service. We only pass dependencies as parameters in any order in our functions. This is where vanilla JavaScript is different from Angular, as the order of arguments in standard JS is strict.

Angular automatically finds appropriate objects that are injected as the $routeParams, $filter, store, and $scope parameters. There are two functions that make dependency injection possible in the Angular framework: $inject and $provide.

We should also mention an issue with dependency injection in AngularJS; a small nuisance you may encounter when you run code minification.

A code minification program reduces dependency names to something like $b and $y for concision. But when executing the code, Angular will look for dependencies by their actual names, which are $scope, $filter, and store in the example above! This is when our program silently crashes. On the bright side, it's very easy to resolve this issue.

As you can see in the example below, we have declared the function TodoCtrl and passed only short names of arguments. Further below, we specifically show what to inject in our function in the necessary order. Therefore, the “s" argument stands for “$scope"; the “r" argument stands for “$routeParams", etc. Angular will find dependencies automatically. This time, pay attention to the order of the arguments.

There is also another way to pass a function and its dependencies – by using an array. The first array elements would be your dependencies followed by the function with short parameters.

Another example of how to inject dependencies into Angular module:

ReactJS

The difference between React and Angular with regards to dependency injection is that React doesn’t offer any concept of a built-in container for dependency injection. But this doesn't mean we have to think of a method to inject dependencies in our ReactJS project. You can use several instruments to inject dependencies automatically in a React application. Such instruments include Browserify, RequireJS, EcmaScript 6 modules which we can use via Babel, ReactJS-di, and so on. The only challenge is to pick a tool to use.

Directives and Templates

AngularJS

Directives in AngularJS are a way to organize our work/code around the DOM. If working with AngularJS, we access the DOM only through directives. For example, AngularJS has many standard directives, such as ng-bind or ng-app, but we can create own directives as well. And we should. This is a powerful way to work with the DOM. On the other hand, the syntax for making private AngularJS directives is rather difficult to understand.

We make our own directives in AngularJS to insert data into templates. The template must have an element with our directive written as an attribute. It's as simple as that. But AngularJS directives, if defined fully, are sophisticated. The object with settings, which we return in the directive, contains around ten properties. Such properties as templateUrl or template are easy to understand. But it’s not so clear how (and why) to define priority, terminal, scope, and other properties. Mastering the syntax of AngularJS directives may be a real challenge.

In summary, in order to bind DOM elements with Angular applications, we use directives, both standard and specific.

ReactJS

ReactJS doesn’t offer division into templates and directives or template logic. The template logic should be written in the template itself. To see what this looks like, open an example from GitHub. You will notice that React's component app.TodoItem is created with a standard React.createClass() method. We pass an object with properties to this function. Such properties as componentDidUpdate, shouldComponentUpdate, handleKeyDown, or handleSubmit represent the logic – what will happen with our template. In the end of the component, we usually define the render property, which is a template to be rendered in the browser. Everything is located in one place, and the JSX syntax in the template is easy to understand even if you don’t know how to write in JSX. It's clear what is going to happen with our template, how it should be rendered and what information will be presented for it by properties.

Such an approach of defining template and logic in one place is better as we spend less time initially on understanding what is happening.

To sum up, both Angular and React are great for writing single-page applications. But they are completely different instruments. Some programmers may say that React is better than Angular or vice versa. What’s really best for a given project, however, depends on how you use these instruments.

Working with ReactJS may seem a bit easier starting out, because you write old-school JavaScript and build your HTML around it. But there are many additional tools you'll have to grasp, such as Flux. In turn, AngularJS implements a different approach organized around HTML. That's why we may see unusual syntax and solutions that seem questionable at first sight. But once you get used to AngularJS, you will certainly benefit from its features.

Recommended Articles