React for the Angular Dev

Preface

Angular and React have dominated the landscape of JavaScript frameworks for some time now. Chances are you probably picked one that suited your needs best and probably stuck with it; after all humans don’t really like change. This article is for those who have been working in Angular and haven’t had a chance to venture into other frameworks and try them out. Before we get started, I want to make this very clear — This is NOT a comparison article of the frameworks. Instead I want to show those using Angular, that haven’t had a chance to get their feet wet in other frameworks, what React looks like.

First some background on me, I’ve been in the industry using JavaScript for almost 12 years now. I’ve built my own frameworks, watched the rise and fall of other frameworks, and used many more frameworks over the years. Recently, I’ve had the chance to actually work on the Angular team building Angular Material. Even more recently a new opportunity presented itself in an industry I’m quite passionate about (cyber-security) and they used React. At first I was hesitant, given my background in Angular, but I decided to jump in head first and give it a chance. This article will summarize that experience over the past 6 months.

Apples and Oranges

When writing about Angular and React a lot of people try to compare them to each other; that’s like comparing apples to oranges. When diving into React, I quickly realized that React is more of a component library whereas Angular is more of an application framework.

What exactly does that mean? Angular comes with all the tools to build an entire application. Things like the router, animations, forms, http, localization, opinions, etc. React is JUST a component library. When you install React you are only getting a component rendering system. Of course you can’t build a true web application with only a widget library.

This is kind of a double edged sword, when you provide all those tools out of the box it really discourages the community to innovate and come up with their own unique systems but if you provide them it makes a really nice developer experience where you can find all the docs in one spot, ensure all your dependencies stay in line with each other and make it easier to hire devs with experience using the same tools.

If I’m completely honest with myself, this was one of the major things I hinged my hesitation on using React to. My experience is building serious web applications, and having to hunt down all the tools to make them is not what I want to spend my time doing. The truth though, is this is not as big of deal as I thought it would be. There are a handful of front runners that have came out with some really innovative solutions to these problems. They are highly active due to the popularity of them and stay in sync with the major versions. A few notable ones I’m using include:

That handles all the major things you need to build a web application these days.

Opinions — Everyones got one

One thing I noticed when I was getting into React is that there is no real style guide for how to organize, structure and format your code. This was really bizarre to me in contrast to Angular, where it was pretty letter-for-letter how to write your code. I did a bit of research and found this tweet by Dan:

When you open the link, it reads:

move files around until it feels right

OK — thats an interesting thought. We could kind of start to see this divergence in the Angular community with the rise of tools like NX that segmented everything into a mono-repo. After doing some research, here are some observations I made:

  • Name the file similar to what it exports. For example, if you have a class like ToggleButton your filename would be: ToggleButton.jsx
  • Make main components/fns that are exported the default export. Personally I hate this, it makes it ambiguous what to name the file. I stuck with named exports.
  • Make index.js export those default exports for the ‘module’. I’m not a fan of this either, it makes searching for components via file system REALLY hard.
  • The same file structure we use in Angular, actually works really well for large React apps too ( /app, /core, /shared ).

Everything is a component

In React, everything is a component. I mean EVERYTHING. If you look at tools like React-Router you will see you even define your routes as components.

When I was first getting started, this felt like insanity to me. These things belong in objects not components but the more I dug in, the more it made sense. One of the hardest problems in all of the JavaScript landscape is change-detection. How do we detect when changes occurs and update our system with those changes.

When those items are composed in objects, it becomes tricky to determine what changed; we’ve side-stepped the problem by making everything immutable but that only solves the diff, how do we know when to check the diff?

If those configuration items are composed using components, we can use the same state tree we use for views to describe our configuration. This allows us to easily hook into the change detection system and participate in all the lifecycle and update processes.

Angular took a different approach to this problem by using Observables via RXJS. Under the hood in Angular almost everything is an observable and the system subscribes to those observables to know when/what to do. Observables are somewhat of a double edge sword too. They are really awesome in some cases and really suck in others. For instance, in order to get values out of an observable you have to subscribe to it. That makes perfect sense except when you get into complicated flows, then you suddenly need to be a RXJS operator expert. This becomes so complicated so quickly that there was a parody presented on it at ngconf 2018.

What do I miss?

When I tell people I’ve been working on React, one of the first questions I get is do you miss it? What do you miss? Here is my breakdown…

  • Community — I’m still fairly involved in the Angular community and continue to be active in open-source and on podcasts like AngularAir but I’m not as involved as I used to be. The number one thing I miss not having as much, is the community. The friendships I’ve made in the Angular community are something that will last a lifetime and have helped me become the dev I am today.
  • Directives — There is no concept of directives in React. Everything is a component. When you want to enhance a component you can use techniques like HOC (or higher-order-components) but this isn’t always as clean and can end up with some complicated code.
  • Style guide — Above I touched on the opinions and how people do things. I do miss some of the opinions that came with Angular. Often it comes down to debates between the team and how to do what, and it’s just easier if there is a standard way of doing things.
  • CLI — React has CRA (create-react-app) but I’ve found it to be a bit limited and until recently it didn’t support things like CSS modules, TypeScript, etc. I ended up ejecting from it. The Angular CLI has always been really strong and easy to use.
  • CDK — The Angular CDK (component developer kit) is probably one of the best, least known tools in Angular. The CDK is a low-level framework for creating components. This framework powers the Angular Material component library. When building components of your own, it’s insanely easy to pick up this library and get all the ‘hard stuff’ like virtual scrolling, portals, a11y, drag and drop, etc.

What do I NOT miss?

The second question I’m asked after “what do I miss”, is “what do I not miss?” Here is my breakdown of that…

  • ZoneJS — There is a chance you don’t even know what this is but if you do then you will probably agree with me here. ZoneJS is the way in which Angular detects changes. It basically monkey-patches many of the browser APIs to detect when something was interacted with and where to capture and run CD on those components. To be completely frank, it was a cool idea that turned out to be a nightmare. The good news is this is slated to go away but not soon enough!
  • AoT- Angular has many performance optimizations baked, one of them is AoT or Ahead-of-Time compilation. AoT traces all your code and optimizes it at build time. Unfortunately this tracing is via static code analysis which means that any dynamic code can not be evaluated and will not work. One of the coolest things about JavaScript is it’s a dynamic language and thus that becomes untrue for many parts of an Angular application. Another problem is its somewhat slow (though getting faster) which means you typically don’t want to run it in dev mode. I can’t tell you how many times I’ve wrote code and deployed it for it to be broken by some odd AoT issue.
  • NgModules- Ever since these came in right before 2.0, I’ve never been a fan. I realize they are probably a necessary evil given complicated dependency relationships and they help enable better static code analysis, but I digress.

I know the Angular team recognizes all these issues and are actively working on improving them, so hold tight!

Closing

Both libraries are iterating and evolving at an incredible pace. People reading this article in 6 months will probably not even relate to some of these problems. It’s been a fun adventure getting to try something new and get out of my comfort zone, I hope this can encourage you to do the same!

I hope you enjoyed the post, if you liked it follow me on Twitter and Github for more JavaScript tips/opinions/projects/articles/etc!