I’ve been building webapps with Angular 2+ and Ember.js since 2016 but I never got the chance to start a React project before.
I once did some changes in an existing react app when I was working at CrazyEgg but they were mostly CSS. I really never had the full experience. I never dug deep into React.
So I decided to do so and I allocated 40 hours to build a simple React CRUD app and dig my way into the source code and to learn how it really works throughout the journey.
React is a library
Angular is not.
Angular is an opinionated MVC/MVVM (or MVW) framework that comes with several smaller packages (or libraries) that handle a wide array of functionalities like routing, http requests, animations, forms,…etc.
On the other hand, react is just a V. It’s really only concerned with the View layer. Woah woah hold on! Don’t get me wrong, I’m not trying to put down React. Actually that kind of specialization gave React a couple of advantages and it definitely beat Angular in some areas that are discussed in the rest of this post.
One could say that React gives you much more freedom. Less boilerplate and faster initial setup. But however if you are going to build a complex webapp using react you need to rely on other libraries like react-router, react-promise, or Redux. Maybe Enzyme for testing. It’s common in React that you may rely on state management libraries like Redux or MobX. Of course we still rely on external libraries in Angularverse like RxJS or NgRx for state management.
One Angular disadvantage that it has a much steep learning curve. Angular architecture is kinda influenced by backend Java frameworks. It is built using TypeScript (a must actually) and it has a clear-ish standard file structure. If you come from backend background, that would be great. Otherwise, you have to understand what is dependency injection and what are static types, add to that some basic OOP concepts like inheritance and polymorphism.
React’s architecture ? It doesn’t have any.
There are some best practices though.
Which can be great if you want to do a simple SPA or crazy animation magic without worrying about the project structure hassle. But it also means a whole lot more decision making if you wanna build a full-fledged app, an analytics dashboard for example. These decisions mostly include picking third-party libraries, choosing how to go about code organization and file structure, sticking with JS or using TypeScript (yes you can TS in react).
Markup
“Let’s have everything in one place” - A wild Facebook Engineer, 2013
React introduced JSX and everyone went crazy. It was controversial for brief 2 years then the frontend community realized it’s actually not that bad.
In JSX you have JS logic inside your HTML …or maybe you actually write HTML inside JS .. wut?! 🤔🤔🤔
// Something like this
const element = <h1>Hello, world!</h1>;
// or even this
const element = (
<h1>
Hello, {formatName(user)}!
</h1>
);
// Look at this
const greetings = ['hola', 'Hello', 'Hey', 'sup'];
const listElement = (
<ul>
{greetings.map(
greeting => <li>greeting</li> // 🤯🤯🤯
)}
</ul>)
On the other hand the conservative Angular has a clear separation of UI and logic. You write your template in the HTML file in TypeScript in the .ts
file like how our parents raised us.
This distinction is highly debatable. While the Angular way is more readable and easy to understand if you come from any formal framework-y experience. JSX has better code completion and compile-time checks as everything is one file. Keep in mind, you also have to learn how to use custom directives like ng-for
and ng-if
to make use of Angular special “HTML on steroids” version.
Data binding
Whether you have a separated template file and TS file or you have them mixed up in a JSX file, at the end of the day you have a UI and some logic that runs it. Say you have an input field in the template and it pulls its value from a JS variable.
In Angular this value can flow in both directions, if you change it programmatically in your TS code or if you changed in your browser writing in the input field. This is called two-way data binding.
React works a little bit differently. You can only change this state (value of the JS variable) programmatically, and then the UI gets updated automatically. But if user changed the HTML input field value from the browser, that doesn’t reflect on the JS variable. This is one-way binding. To achieve two-way binding in React we rely on callbacks and DOM events.
// Updating state in React
<input value={someData} onChange={({ target: { value }}) => this.setState({ someData: value })} />
DOM Manipulation
If you know what you are doing, React is fast. Really fast.
The reason behind this is that React uses a Virtual DOM which basically diffs the DOM tree looking for changes and then only updates the changes (like how git works).
Angular uses Regular DOM that traverses the whole tree till it finds the target element it wants to change and then edit it.
In the grand scheme of things this difference in performance is negligible unless you are doing crazy stuff with lots of elements in the page (Say more than 1500). This can actually block the main thread of the JS engine and freeze the UI if you are not careful.
Unit Testing
Using Angular CLI you can set up your project to include tha boilerplate file provided by Jasmine testing framework which runs by Karma test runner. You can also use Karma to replace Jasmine with other frameworks like Mocha or QUnit. Karma plays very well too if you want to integrate with continuous integration services like Jenkins, TravisCI, or CircleCI.
React uses Jest out of the box with no need to do any configuration. You can also use AirBnb’s Enzyme library next to Jest. Enzyme mimics JQuery API to facilitate DOM interactions in tests.
That’s all folks!