I offer the readers of "Habrakhabr" a translation of the article "How I learned to stop worrying and love React" .If you ask me what I thought about
React two months ago, I would say ...
Where are my templates? What does this crazy HTML do in my javascript? JSX looks weird! Rather! Burn it!

This is because I did not understand him.
')
But I assure you, React is definitely the right way. Please listen to me.
Good old MVC
The root of evil in an interactive application is state management. The “traditional” approach is MVC architecture or some of its variations.
MVC assumes that your model is the only source of truth, the whole state lives there. Views are derived models and must be synchronized. When the model changes, the presentation changes.
As a result, user interaction is recorded by the controller, which updates the model. So far so good.
Render views when the model changesIt looks pretty simple. First, we need to describe our view — how it transforms the state of a model into a DOM. Then, whenever the user does something, we update the model and re-render everything. Right? Not so fast. Unfortunately, not everything is smooth here. For 2 reasons:
- In general, the DOM has some state, such as the contents of text fields. If you re-render your DOM completely, then this content will be lost;
- DOM operations (such as deleting and inserting nodes) are really slow. Continually re-rendering everything leads to terrible performance.
So how do we keep the model and presentation in sync and avoid these problems?
Data binding
Over the past 3 years, the most common framework feature introduced to solve these problems was data binding.
Data binding is the ability to keep your model and views synchronized automatically. Usually in JavaScript these are your objects and your DOM.
This is achieved through the ability to declare dependencies between pieces of data in your application. Changes in the state will be distributed throughout the application and all dependencies will be updated automatically.
Let's see how it works in practice in some well-known frameworks.
Knockout
Knockaut stands for the
MVVM (Model-View-ViewModel) approach and helps implement part of the View:
// View (a template) <p>First name: <input data-bind="value: firstName" /></p> <p>Last name: <input data-bind="value: lastName" /></p> <h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
And voila. Changing the value of any input will provoke a change in the span. You have never written code to connect it. Great, huh?
But wait, what about the fact that the model is the only source of truth? Where does the ViewModel get its status from? How does she know that the model has changed? Interesting questions.
Angular
Angular describes data binding in terms of keeping models and views synchronized. From the documentation:

But ... should the presentation communicate with the model directly? Are they closely related?
In any case, let's look at the hello world:
From this example, it seems that the controller has a status and behaves like a model, or perhaps as a ViewModel? Assuming the model is in a different place, how does it sync with the controller?
My head starts to hurt a little.
Data binding issues
Data binding works great on small examples. However, as your application grows, you are likely to encounter some of the following problems:
Declaring dependencies can quickly lead to looping
The most common task is to deal with the side effects of changing your state. This picture from the
introduction of Flux quite clearly explains how the hell of dependencies starts to sneak up:

In this case, can you predict what changes will occur if there is one change in one model? It is very difficult to talk about code that can be executed in a completely arbitrary order when any dependency is changed.
The pattern and display logic are artificially separated.
What is the role of performance? Presentation of data to the user. What is the role of the ViewModel? Presentation of data to the user. What's the difference? No.
In the end, the view component must be able to manipulate its data and present it in the desired format. However, all template languages ​​are essentially disabled: they can never achieve the same expressiveness and power as the code.
Quite simply, {{# each}}, ng-repeat and databind = “foreach” are all a bad replacement for the native and trivial for loop in JavaScript. And they can not go further. No filter or map.
Data binding - hack around re-rendering
The holy grail of simplicity is not discussed. Everyone always wanted to re-render the entire application when the state changes. Thus, we could stop dealing with the root of evil: states change over time - we could just describe that our application represents any particular state.
Enter React from Facebook
Turns out they did it. React implements a virtual DOM, which seems to give us the Holy Grail.
Anyway, what is a virtual DOM?
I'm glad you asked! Let's look at a simple example of React.
var Hello = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; } }); React.render(<Hello name="World" />, document.getElementById('container'));
This is all you need for the React component. You must have a render method. Difficult, yes?
Good, but what about the <div>? This is not javascript! Not exactly him.
Your new friend, JSX
Actually, this code is written in JSX. Super set of JavaScript, which includes the syntax of brackets to define components. The code above, when compiled into JavaScript, will actually become like this:
var Hello = React.createClass({displayName: "Hello", render: function() { return React.createElement("div", null, "Hello ", this.props.name); } }); React.render(React.createElement(Hello, {name: "World"}), document.getElementById('container'));
Have you noticed createElement calls? These objects make up the implementation of the virtual DOM.
Pretty simple: React first collects the entire structure of your application in memory using these objects. It then converts this structure into actual DOM nodes and inserts them into your browser's DOM.
OK, but what's the point of writing our HTML with these weird createElement functions?
Virtual DOM - fast
As we have already discussed, DOM operations are ridiculously expensive, so the DOM should be changed as few times as possible.
The virtual DOM in React, however, does it really quickly by comparing the two trees and finding exactly what has changed between them. Thus, React is able to calculate the minimum number of changes required to update the DOM.
Practically speaking, React can compare two DOM trees and calculate the minimum set of operations that need to be performed. This means two things:
- If text fields with text are rendered, then React expects that there is content and will not touch it. No more losing condition;
- Comparing virtual DOMs is not expensive at all, so we can compare them as much as we like. When the diff is ready to actually change the DOM it will do this with a minimum of operations. No more slow layout.
Remembering 2 problems with re-rendering the whole application when changing state?
Has passed.
React MAP State in DOM
Virtual DOM rendering and diffing is the only magical part of React. Its excellent performance allows us to have a much simpler architecture. How simple?
React components are idempotent functions. They describe your UI at any given time. Just like a rendered server application.
Pete Hunt, React: Rethinking best practices
This is all what the React component really should be. It displays the current state of the application in the DOM. You have all the power of JavaScript to describe the user interface: loops, functions, scopes, compositions, a full-fledged template language.
var CommentList = React.createClass({ render: function() { var commentNodes = this.props.data.map(function (comment) { return ( <Comment author={comment.author}> {comment.text} </Comment> ); }); return ( <div className="commentList"> {commentNodes} </div> ); } }); var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.props.data} /> </div> ); } }); React.render( <CommentBox data={data} />, document.getElementById('content') );
Start using React today
At first glance, React may seem a bit complicated. It offers very large paradigms, which is not always convenient. However, when you start using it, the benefits become clear.
React has excellent
documentation . You should try it and follow the tutorial. I'm sure you will love React, if you give him a chance.
Good coding.
Original article:
How I learned to stop worrying and love ReactArticle author:
Guilherme Rodrigues