From AngularJS to React

For those who have programmed a lot using AngularJS, the first impression when coming across a React component may not be the best. Seeing JavaScript and HTML sharing the same space is likely the most significant impact. But do not get carried away by appearances. React is far less strange than the first impression might suggest.

Before we dig deeper into the differences between AngularJS and React, we need to have an overview of the structure that supports React. The JavaScript code that we will see in a React component is not supported natively by the language. Another still very incipient feature is the use of modules. Two development tools come into play to make those features available: Webpack and Babel.

Webpack

Webpack allows us to organize the code into modules. Every variable or function is private in a module and has to be explicitly exported to become public. Public content is visible and can be imported by the other modules. That said, popular strategies like IIFE (Immediately Invoked Function Expression) are no longer necessary to avoid polluting the global scope with undesired variables or functions.

On the Webpack configuration file, we set a module as an entry-point. Then Webpack will resolve the modules imported by the entry-point, as well as all the other modules imported by subsequent modules. Through a long module-by-module scan, Webpack creates a dependency tree and connects them into a single file called bundle.

As we can see in the image, all the necessary modules to resolve the entry-point were included in the bundle. The bundle contains index.js (entry-point), a.js, b.js e c.js. Since no module imported d.js during the entry-point resolution, it was left out. This is nice because it means that modules that are not effectively used by the application are not bundled, avoiding unnecessary weight.

Babel

Compared to Webpack, Babel is much simpler to understand. It is a code transpiler and allows us to use JavaScript language features that are not fully supported by browsers yet. In the case of React, it goes a little further and, through a specific preset, makes it possible to use HTML within JavaScript code. This syntax is popularly called JSX.

In this repository, you can check the .babelrc and webpack.config.js configuration files containing only what is minimally required to bundle and run a React application.

Template Engine

The way to handle HTML is where you will see most of the differences between AngularJS and React. Bindings, Loops and Conditional Rendering work radically different in React.

Bindings

AngularJS has a philosophy called Two-Way Data Binding. Through the ng-model directive, AngularJS binds the controller variable to the template and vice versa. When the variable changes on the controller, the template is automatically updated. And when the user changes the variable on the template, the controller gets updated as well. Also, a child component can change the value of a property passed by its parent. That is, not only parents change a property value given to its children, but also children change the property values received by their parents.

React treats binding differently. It is One-Way Data Binding. The value of a variable present on the controller reflects automatically on the template, but when the variable changes on the template, its value is not automatically updated on the controller. You need to handle this change manually. Component property values can only be updated upside down too. That is, from the parent to the child, not otherwise.

Playground: Two-Way Data Binding, One-Way Data Binding.

Conditional Rendering

It was also using another directive that parts of a template could be conditionally rendered in AngularJS. All you needed to do was passing a Boolean variable to the ng-if directive to decide if the element and its children would be shown or not.

React uses the resources of the JavaScript language to achieve the same result. If statements, ternary and logical operators.

Playground: Ng-if, If Statement, Operador &&, Operador TernĂ¡rio.

Loops

Following the same way used to conditionally render parts of a template, loops made with the ng-repeat directive in AngularJS are done in React using plain JavaScript like map, for instance.

Playground: Ng-repeat, Map.

As we see, one of the traits that separate Rect from AngularJS so much is how the template is perceived. To illustrate that difference, some developers use to say: AngularJS puts JavaScript in HTML, React puts HTML in JavaScript.

But the main differences between AngularJS and React are not limited to the template engine. The Component Lifecycle API changes a lot as well.

Lifecycle Hooks

Lifecycle hooks give us the necessary conditions to perform specific tasks. When some tasks only can be done after the component template has already been rendered, we can use the component initialization hook, for example. On the other hand, if we need to perform a task at the moment in which a component is removed from the DOM, we can use the component termination hook.

Initialization/Mounting

The hook that represents the component initialization in AngularJS is $onInit. This is the function AngularJS runs at the moment in which component is fully ready for use. That is, the template is rendered, and all the variables present on the controller are bound to it.

Tasks that need to be performed in specific moments of the React component lifecycle are passed to a function called useEffect. Not so intuitive, the name of this function relates to the term side effect. Within useEffect we can be sure that the task will run only after the component is mounted.

Playground: $onInit, useEffect.

Destruction/Unmounting

Like the tasks that should be run when the component is already mounted, some other tasks need to run right before component unmounts. Consider some task adding an event listener to the document at the moment the component initializes. That listener must be removed from the document when the component is removed from the DOM. Otherwise, every initialization of that component will add one more listener causing unexpected behavior.

The AngularJS hook that allows us to run a task right before a component is removed from the DOM is called $onDestroy.

The hook used in React to do this keeps the same, useEffect. In the previous case - initialization, we just passed a function to the hook that will be run at the moment in which the component is fully mounted. When you need to run a task right before the component is unmounted, the function passed to useEffect must return another one. That other one should contain the tasks that will run right before the end of the component life.

Playground: $onDestroy, useEffect.

As we noticed, the underlying logic on how to handle a component does not change too much from AngularJS to React as the code appearance may suggest. Once you understand the differences regarding the form, any developer familiar with AngularJS will have no trouble developing React components.