- Published on
Why I switched from Angular to React and never looked back
- Authors
- Name
- Filip Sobczak
There are all kind of technical reasons why you might want to move from AngularJS to React, like:
Rendering speed
React's virtual DOM feature handles the UI updates much more efficiently. React only touches the DOM when necessary, and DOM operations tend to be the biggest performance bottleneck when it comes to rendering.
Bundle size
React is just a library. Yes, it's often used with other libraries like Redux, but all things considered, the final bundle tends to be more lightweight than AngularJS, which is a framework that tries to do everything.
Architecture simplicity
React's component-based architecture allows to break down complex UIs into manageable pieces, resulting in more maintainable and reusable code. AngularJS often felt bloated and overly complicated, all its directives, controllers and services.
In the end what made the biggest difference for me was the ease of use and development, and that brings me to my biggest issue with AngularJS...
AngularJS two-way data binding vs React's unidirectional data flow
I often joke that I made my career because of how confusing the data flow in AngularJS is. Often I was the only one in the room that took the necessary time to understand it, and it felt like I had a secret to developing with AngularJS.
Let's take a simple example, and try to modify variable foo
on the parent scope:
<div ng-controller="MainController" ng-init="foo = 1"> <!-- parent scope -->
<p>Outer scope:</p>
<p>{{ foo }}</p> <!-- if you click Action, still foo=1 -->
<div ng-if="foo"> <!-- child scope -->
<!-- sets primitive on child $scope -> FAIL -->
<button ng-click="foo = 2">Set foo = 2</button>
</div>
</div>
Because AngularJS scope's inheritance uses JavaScript's prototypal inheritance, when you click the button, the child scope variable foo
gets. For this to work, you need to reference the object in the parent scope:
<div ng-controller="MainController" ng-init="myObject = {foo: 1}"> <!-- parent scope -->
<p>Outer scope:</p>
<p>{{ myObject.foo }}</p> <!-- now after you click Action, myObject.foo=2 -->
<div ng-if="foo"> <!-- child scope -->
<!-- mutates myObject on parent $scope -> SUCCESS -->
<button ng-click="myObject.foo = 2">Set foo = 2</button>
</div>
</div>
Not very straightforward, right? After a while, someone implemented a linter that warned every time a scope variable was used without a ".", but it still feels obscure.
Add on top of this the four types of data bindings for directives:
<
- one-way=
- two-way&
- function@
- only strings
and it's easy to see why the data flow in AngularJS is so confusing for everyone.
React's unidirectional data flow, on the other hand, follows a clear and predictable path. Data flows in a single direction, from the parent components to the child components. It's easy to track where modifications are happening and how they affect the UI.
This clear and predictable data flow also paved the way for centralized state management libraries like Redux. Redux makes it even easier to trace when, where, why, and how your application's state changed. You can also use it with AngularJS by implementing a one-way data flow, but with React, it feels much more natural, and Redux seems to complement it perfectly."