Arguing for ReactJS
The two main objections to React are:
- Its incompleteness — it’s not a “fullstack” framework like Meteor or Angular. It doesn’t have a router, a model system and many other common framework features. People say it’s just the “V” of the MVC, but this is far from accurate, and we’ll discuss that.
I’ll try to address these, and also add some weight to React’s strengths. Here we go!
First of all, what is React?
In this example we have a button that, when clicked, calls the method increment. The method increment calls setState, setting the count to the current count plus one.
The setState method renders the component again. The way it does that is what makes React and its clones different from current approaches. In a nutshell, it keeps a DOM in memory, called virtual DOM (shadow DOM is something else), then it does a diff between this DOM and the one displayed in the browser. Based on this diff it defines a list of changes to be made — think about createElement – and applies them.
Of course there are more concepts to get acquainted — like props, the different tag attributes, etc — but this is the bulk of it.
Addressing negative arguments
Incompleteness. Vice or virtue?
When Rails came, one of its main selling points was its “fullstackness” (I hope it’s a word). Since, most alternatives to it mimicked the completeness of the solution, having a database abstraction layer, a routing system, a templating system and so on.
The alternatives, AFAIK, started with Why’s Camping, a microframework written in very few LsOC, and then came Sinatra, CherryPy, Flask, Express and many others. But the truth is all these still emulate the framework concept, they are just thinner and generally less opinionated. And the main selling point is that, since they require less hassle to start they are more appropriate for smaller apps.
The inherent incompleteness of React is way different. React is not just a thinner version of Angular, it is something completely different. It solves one specific problem — web components – very well. So here the discussion shouldn’t revolve around what size of project it is appropriate. By the way, React is clearly focused on performance and runs Facebook’s comment system, so there’s no doubt it can handle gargantuous scales.
The relevant discussion is whether you really need all the weight of a framework, and also how can you build all the pieces you need around React. The first important thing we have to note is that on the back-end size doesn’t matter much. If you have to download a 1GB framework, but the result is a lean and fast app, this is not an issue. Contrariwise, on the front-end size matters a lot. Anything your framework adds will mean more load in the end result.
Also, there are amazing pieces to rebuild the feeling of a complete framework. I see a lot of people mixing Backbone models with React. There are also fairly nice libraries to add routing. But the main response of React’s community is Flux, that is more to a way you should architecture your app than a specific set of tools.
Is React just the V of the MVC?
As Andre Medeiros points out in his great presentation, React goes far beyond the V. This is because a React component have state, so, in a sense, it’s a Model, it handles the mapping from inputs to state changes, so it’s also a Controller, it renders the component, so it’s a View — or Presentation as he puts it – and they also communicate and depends on other components. So the assumption that all you have to do is to find a suitable model and controller libraries is just false.
And since React conflates all these things in one single concept — the component — there is big room for messy, highly coupled code that doesn’t separate concerns properly.
Why mixing HTML and JS? …What? CSS too???
The holy grail of web development, 10 years ago, was the separation of HTML, JS and CSS. Everything should inhabit in its own kingdom, separated by files and folders, only referencing each other using includes.
This separation, although natural, is just a separation of technologies, not of concerns. React challenges this separation by stating clearly that the separation should be done by components. Components may mix different technologies, but they are a well encapsulated, cohesive element that comprehends both look and feel and behaviour. If this behaviour spreads over different technologies and languages, so be it.
The gut reaction we have is, IMO, pure unjustified prejudice. Within some hours, it feels very natural. All responses I’ve found of people using React in the web is the same. Suddenly, not having to open 2 different files in tabs (or splits, whatever floats your boat) makes your workflow even more productive.
There’s even some people advocating moving CSS to the domain of the component. Before you throw up, take a look at this nice introduction on the subject by Christopher Chedau.
There is an ecosystem
As I write this article, React just passed Ember in number of stars on GitHub. It’s only behind Backbone and, of course, Angular, but growing way faster than its “competitors”.
React is a Facebook project and is what fuels FB’s comment system and most of FB’s projects. It’s also largely used on Pinterest, AirBnB, Khan Academy and a plethora of other startups. Atom, the “hackable editor”, is now built on it and I heard Microsoft is also supporting the project.
There are certainly some things missing from a mature community. Online courses, canonical tutorials and conferences are among these, but I’m sure they will be addressed soon.
Easier to reason about code
One of the main positive arguments given about React is that it’s easier to reason with. This is definitely a true statement, and its power and importance can’t be neglected.
Reasoning about code, as I understand it, is not just about having uncoupled and cohesive parts. It’s the path your mind goes from understanding a problem, to seeing where things happen (events, data flows…), accessing these parts quickly to finally fixing a problem.
One interesting insight is that when we think about software quality we should not only focus on number of bugs — as we’ve been preaching in the Agile community, we “shouldn’t have bugs” –, but also on the amount of time taken to fix a bug. When I was acquainted to this idea, I remembered of a bug that took a year or so to be fixed, generated terrible memory leaks and increased the response time of the solution considerably, specially on usage peaks. Based solely on number of bugs, it is conceivable that you can have just a few of ‘em and still have a very poor solution.
Also, the time to fix a bug reflects how difficult it is to reason about the code. If it takes a long time it means developers have a hard time understanding the issue and vice versa.
React makes easier to reason about code for many reasons. The main one is the concept of stateless DOM. One simple way to visualize this is to think about how we toggle things in vanilla jQuery.
This looks pretty simple. But the question is how do you know whether the div is shown? Well, you would say “if you click any even number of times on the button, it is shown, and if you click any odd number of times, it is not shown”.
So here the question changes dramatically. You would say “It is shown if it is visible”. As a rule of thumb your code is easy to reason if you can express what your code is doing is such clear terms.
Here’s a magic word. In the back-end world, reusing pieces of code is a reality. Think gems or eggs. But in the front-end it looks like we have to rebuild everything every new project. It is true that things like a DOM traversal tool or a URL parser are easily reusable, but when it comes to the content itself it looks like every project is a different beast and every piece of a layout is an idiosyncratic being that rejects gregarious tendencies.
I admit I still haven’t seen components moving from one project to another, but I can’t see why atomic things like alert boxes and buttons and even more “molecular” or “organic” things like articles and to-do lists can’t be used as they are, as long as you separate the visuals from the markup and behaviour.
It will be interesting to see also how reusability will happen between companies and how people will build open source libraries with implemented components. One nice example is MaterialUI.
Growing a project
Most front-end projects I’ve worked on started small and eventually grew considerably. Some of them were refactored to a different framework at some point, or injected some ad hoc structure to handle the complexity increase. On both cases this demanded a fair investment of time and effort, halting some product features — but as any important refactoring it gave more development speed later, of course.
One thing that seems relevant in a component-based development, is that it fits very well this stages where a project goes through. I can’t imagine a project that starts with just a small set of components and a nice way to flow the data to require such drastic changes, since the parts are very stable.
As you noticed I haven’t discussed much about Flux (and Reflux, one of its implementations). That’s because I’m leaving it for another article.
As a last remark, I would love to see more arguments that I’ve missed both pro and against React in the comments.