Unconventional React Review

Original author: James Shore
  • Transfer
Hello, Habr!

We at  Hekslet love our technology stack :) When we tell others, many envy: Rails, Docker, AWS, React JS. We use the fact primarily to create a web-based environment for the development of the Hexlet-IDE , which allows our users to perform the exercise of developing applications and interacting with the virtual machine directly in the browser.

Today we are publishing a translation of the article “An Unconventional Review of React” by James Shore, lead project of Let's Code: Test-Driven JavaScript.

I liked him. I did not expect this.

For special releases of Let's Code JavaScript in August and September, I studied React .

In case you are new to React: This is a front-end web development library. Using it, components are created: short, not-quite-HTML tags that can be combined to create an interface.

React is famous for its unconventional solutions: the implementation of a virtual DOM, creation of interface elements in JavaScript instead of templates, creation of the JavaScript supernet - JSX, which allows you to embed non-quite-HTML in JS code.

With these solutions, development moves away from the DOM manipulation scheme - add this element, hide another element with the effect, and update this text field. Instead, you describe what the DOM should look like now. The reaction takes the hard work of identifying what you need to do so that the DOM actually looks like you said.

For example, in The code that I wrote for the review has a table that should change every time the configuration fields change. You might think that the code will be full of scary logic for DOM manipulation, but in fact there is no code for manipulation at all. Here it is :

/** @jsx React.DOM */
// Copyright (c) 2014 Titanium I.T. LLC. All rights reserved. For license, see "README" or "LICENSE" file.
"use strict";
var StockMarketTableCell = require("./stock_market_table_cell.js");
var StockMarketTableRow = module.exports = React.createClass({
  render: function render() {
    var year = this.props.stockMarketYear;

This is the essence of the React, and in this it differs from others. The only question is: is he good?

Alternative Survey Criteria

Usually, when you read a review of the front-end of a framework or library, you will learn about its size, or about what famous people and companies use it, or about its performance. Yes, all of this is important. But the most important question for me sounds simpler:

Over the next 5-10 + years, when I support my product, will this code bring more benefit or suffering?

It doesn't matter how much time the library saves me during initial development. Oh no. Much more important is the cost of support throughout the life of my application.

For this, I have five criteria.

1. Closure (Lock-in). When I decide to upgrade to a new or better framework (or library), how difficult will it be to switch?

2. Stubborn architecture (Opinionated Architecture). Can I solve problems the way my application needs, or should I obey some ideas developed by the authors of the framework?

3. Side complexity (Accidental Complexity). Am I wasting time solving my problem or struggling with a framework?

4. Testing. Can I just test my code, without too much trouble with mock objects?

5. Compatibility with search engines (Search Engine Compatibility). Will I have to dance with a tambourine to make search engines index my site?

I rated React in each category using a (uiii!), (Bueee!), Or ⚇ (neither here nor there).

1. Closure - ⚇ (neither here nor here)

Let's be honest: when you decide to say goodbye to React, you will have to rewrite the interface from scratch. There is no normal way to hide React behind a layer of abstraction, and the code of the React interface is not like anything else. So everything is pretty closed.

But why didn’t React get a sad face?

Two points save the React. First, React provokes putting application logic outside the UI, so you don’t have to rewrite the entire application.

Secondly, the React API is relatively small. There are not many common ground (see paragraph 3). This means that there is less chance of breaking something when updating the React. Also, React is easy to use in isolation, for a separate part of the page, so you can gradually migrate from React when the need arises.

2. Upright architecture - (uiii!)

React is a library, not a framework, and it is noticeable. React does not dictate application architecture. I had no problems connecting my existing and  obviously strange code to React.

Some people find stubborn architecture a good sign. “This allows me to understand how to structure the code.” I prefer the opposite. The structure of the application should be dictated by the requirements of the application. The framework cannot predict these requirements, and they will change with the development of the application.

The React contains an architectural pattern called Flux , but it is completely optional. This is just a way to talk about the structure of the code, not the mechanism built into React. It should be so.

3. Collateral complexity - ⚇ (neither here nor here)

Very little needs to be known about the React, and it seemed to me simple and straightforward. There are only a couple of points (the difference between “props” and “state”), only a couple of concepts (how to manage state; immutable render methods) and several methods for implementing a typical component. My most complex component contains as many as three React methods. In most cases, one render () is enough.

Fly in the ointment is a virtual DOM. This is an impressive achievement, a key piece in React ... but it can turn out to be a holey abstraction . As soon as you see a new or advanced DOM feature, you run the risk of a fight with React. For example, CSS animations caused problems for some time , and focus control is still naughty .

Now, it seems, the React team manages to rule everything. But what will happen in five or ten years when React is no longer the most fashionable thing? Browsers continue to evolve, and before choosing React for your project, ask yourself: am I sure React will keep up with all the innovations necessary for my application?

4. Testing - (uiii!)

The story of testing React looks a bit immature. She barely reached for a smiling face.

At first glance, React provides a simple API for testing, and it seems that there is everything you need. You can render a component and search the DOM tree with a good set of functions. You can simulate events. You can make mock components, but I was pleased that I never needed them.

There is not much documentation, not enough examples and design recommendations, especially when compared with the rest of the React documentation. This only maintains a sense of immaturity. But the main problem is that I could not find a way to compare the components. Even in a relatively simple application, your components will contain components, and you do not want the tests to know something about the details of implementing additional components.

For example, the ApplicationUi component contains the StockMarketTable component . I want to check if the table is updated when the configuration changes. To do this, I wanted to check the table with the finished hardcode:

it("updates stock market table when user configuration changes", function() {
  var expectedTable = ;
  var actualTable = TestUtils.findRenderedComponentWithType(app, StockMarketTable);
// но как делать сравнение?

As a result, I circumvented the problem by digging into the private details of the implementation of the Recata, rendering the components in a static HTML and comparing the result. Here is the code.

function checkComponent(actual, expected) {
  var actualRendering = React.renderComponentToStaticMarkup(actual._descriptor);
  var expectedRendering = React.renderComponentToStaticMarkup(expected);

It works, but in the event of a crash, it generates a terrible error message, and this code depends on the details of the React implementation. ( I had to visualize the runtime object graph!) Perhaps there is a better way - and there must be a better way - but I did not find it.

In addition to this not so small problem, testing the React is a pleasure. Check out ApplicationUi tests . They are wonderful in their simplicity, understandable and do not contain mocks. No test contains more than two lines, and this is the most complex component of the entire application.

5. Compatibility with search engines - (uiii!)

The reaction managed to make a small miracle: they made a front-end framework that has no problems with search engines.

Thanks to the virtual DOM, React applications can be rendered on the server side using Node.js. This means that you need only one render channel for both search engines and real users. This also means that pages are displayed immediately after they are submitted. No waiting for document ready events or loading all JS. React can be used to submit static markup, without client code at all.


Bottom line: I recommend.

React is a surprisingly well-assembled library. It seemed to me simple, intuitive and easy to use. If you are looking for a front-end library for complex applications or even for complex widgets for an existing page, you should pay attention to React. It’s not perfect, and it’s worth considering the potential problems with the holey DOM abstraction, but it’s very good. Recommend.

Also popular now: