How to Replace the Angular Stack with React plus a few NPM modules
<p>As you can tell from the content of my blog posts, I’ve been practicing and preaching Angular.js for quite some time now. It is an extremely productive web framework that felt like a big step forward from my days doing jQuery “sprinkles” and then Backbone.</p> <p>But then recently, I started playing with Facebook’s <a href="https://facebook.github.io/react/">React</a> framework. And while I’m still not quite as productive as I was with Angular, I absolutely love the code that I’m writing. And on top of that, it has opened my eyes to a whole new paradigm for creating user interfaces.</p> <p></p> <p>I won’t make this an article comparing and contrasting the libraries (a google search will probably turn up dozens of these), but here are the main reasons I’ve made the switch:</p> <ul> <li>Small API surface area - you can learn 90% of React in 1 day (unlike Angular, where <a href="feelings_about_angularjs_over_time.png">this is the common learning experience</a>)</li> <li>Due to the efficiency of the virtual DOM, you don’t have to worry about updating the DOM. You just write a single <code>render()</code> function that is run over and over and applied in an efficient manner. It makes writing your views more similar to how you’d write them on the server because your view is simply a reflection of your current state. Angular’s 2-way binding is nice, but it comes at a cost of speed and complexity.</li> <li>The “Everything is a component” paradigm is an extremely pleasant and simple way to create user interfaces.</li> <li>Everything is just javascript. Even the “templates”.</li> </ul> <p>And I’m sure there are others. Angular is still a great framework, but at the end of the day, I enjoy writing code in React quite a bit more. And interestingly enough, while I had previously been under the impression that React was a 1-trick pony that you used when performance was a big requirement, the fact that it’s extremely fast probably wouldn’t make the top 10 reasons why I would pick it over other frameworks.</p> <p>One of the biggest differences between the two libraries is their scope (and this can be both good and bad). React only provides the view layer, while Angular provides quite a bit more, such as libraries for promises, http, dependency injection, etc, etc.</p> <p>So how do we replace all these concepts in the React world? Let’s go over them one by one.</p> <h2 id="routing">Routing</h2> <p>Angular has a new router that I hear is great, but all my experience had been with <a href="https://github.com/angular-ui/ui-router">UI-Router</a>, which I generally liked. There is a React-focused router called <a href="https://github.com/rackt/react-router">react-router</a> that is really fantastic. It is highly inspired by Ember’s built-in router, but uses React’s JSX syntax to structure your routes.</p> <h2 id="promises">Promises</h2> <p>Promises are in most JS apps these days and ES6 (the next version of Javascript) will have built-in promises, but until then, we will need to use a library. Angular includes the very nice <a href="#">$q</a> library that, as of version 1.3, uses a syntax fairly similar to that of ES6. For a non-Angular project, we have a few choices. First, there is <a href="https://github.com/jakearchibald/es6-promise">es6-promise</a>, which is a polyfill that just includes the exact functionality that ES6 will have. But there was one feature that I missed from $q, which was the <code>finally()</code> method. So if you need this feature, I recommend the <a href="https://github.com/petkaantonov/bluebird">Bluebird</a> library.</p> <h2 id="http-requests">HTTP Requests</h2> <p>For my early Angular projects, I used <a href="https://github.com/mgonto/restangular">Restangular</a>, but in later projects, I found myself just using <a href="https://docs.angularjs.org/api/ng/service/$http">$http</a> with a service for each resource. <a href="https://github.com/mzabriskie/axios">Axios</a> is a library that is very similar to (and, in fact, inspired by) $http. Like $http, it is promise-based, automatically transforms JSON, and allows you to setup request and response interceptors.</p> <h2 id="modules-dependency-injection">Modules / Dependency Injection</h2> <p>Angular includes its own dependency injection framework for importing other libraries. It has a quirky syntax, but it generally works pretty well. But it is Angular-only, so it can be a bit awkward to pull in 3rd party libraries that weren’t built for Angular. In React, you can just use NPM modules, which are widely supported, by using a bundling library such as <a href="http://webpack.github.io/">WebPack</a> or <a href="http://browserify.org/">Browserify</a> (I suggest Webpack). Then you can just require other modules like so:</p> <div class="highlight"><pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">otherLib</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">some-other-library</span><span class="dl">'</span><span class="p">);</span> </code></pre></div> <h2 id="unit-testing-mocking">Unit Testing & Mocking</h2> <p>Easy unit testing is one of my favorite things about Angular, so it’s great to know that their test runner, <a href="http://karma-runner.github.io/0.13/index.html">Karma</a>, isn’t specific to angular and can just as easily be used with React.</p> <p>Facebook actually has their own test runner and flavor of Jasmine called <a href="https://facebook.github.io/jest/">Jest</a>, which has two things going for it: It’s easy to setup and it auto-mocks your dependencies by default. But I found it to be painfully slow and quickly switched to <a href="http://mochajs.org/">Mocha</a> plus <a href="http://chaijs.com/">Chai</a> and running tests using <a href="http://karma-runner.github.io/0.13/index.html">Karma</a>. And there are a few testing helper libraries included in React that can be used with any framework.</p> <h2 id="conclusion">Conclusion</h2> <p>When I first moved from server-generated “traditional” web apps (and some light backbone apps) over to Angular, it felt like a huge step forward. While moving to React may not be as big of a step in terms of productivity, it feels like a huge move forward in terms of code simplicity and cleanliness. I’m officially a convert, and I highly suggest that you check it out. And now that you know the basics of the React ecosystem, there’s no excuse not to give it a try.</p>