Yes, React is taking over front-end development. The question is why.
By Samer Buna
Translator: Yu Bolun
Please indicate the source of reprint.
TL; DR is too long to see
- The main React core API is very small, and it’s pretty quick to get started if you’re familiar with es6/7 and other new syntax and Modern JavaScript stacks.
- React implements an abstract layer of “virtual DOM” to represent the user interface, which means you can render the React user interface on any device or platform (Web/Native/VR) as long as the appropriate renderer is available.
- React takes a declarative approach to writing the user interface. You simply describe to React what you want the interface to look like, and then plan out how the app’s state data will change. React updates and renders will do the rest for you.
- Note: No framework or library is faster than native JavaScript. React isn’t faster than plugging into the DOM, but the “virtual DOM” and “core Diff algorithm” implemented by React can update only necessary parts of the interface rather than replacing the whole thing. This is something that is hard to do manually with the DOM.
Here are a few reasons React has become so popular:
- Using the DOM API is difficult. React implements a virtual DOM that is much more developer-friendly. It acts as a proxy between the developer and the real browser.
- React allows developers to describe their user interfaces declaratively and model the state of those interfaces. This means that the developer describes the interface only in terms of its final state, such as functions, and does not need to think about procedures and intermediaries. When some event trigger application state changes, the React will automatically update the user interface according to the specific situation (imagine our interface is an animation, the React can let’s cut the animation into a frame of a frame of fragments, we only need to focus on one of the pieces, what are the changes and fragments, as for how to change, how to process, React automatically handles this for us.
- React is pure JavaScript, and you only need to know a few core apis, plus a few simple functions to use. In addition, as long as your JavaScript skills are good enough, you can be a great React developer. It’s also easy to get started. Once you’re familiar with JavaScript, React can be used in just a few hours.
But there’s more to it than that. Let’s talk about it more carefully. The first is the Virtual DOM and the core scheduling algorithm. We can demonstrate the value of these implementations with examples.
React is officially defined as a library for building user interfaces. There are two important parts to this:
1. React is a library, not a framework. It’s not a complete solution, and we need to add other libraries to work with React (unlike Angular). React focuses on one thing and does it well.
2. React Focuses on what needs to be done: building the user interface. A user interface is the part that a user can see and interact with a program through. Generalized user interfaces are everywhere, from buttons on microwave ovens to control panels on spacecraft. As long as the device supports JavaScript, we can write an interface for it using React.
Browsers can run JavaScript, so React is a natural way to describe the Web interface. Notice that I’m using the word description here. This is what we usually do with React. We just tell React how to build a specific user interface. Without React, we would have had to write it manually using raw Web APIs and JavaScript.
So when you hear a definition like “React is declarative,” it means literally, we use React to describe the user interface (just tell React what it is or how to do it). React will take care of the rest, translating our declarative descriptions into the user interface in the browser. React features are built on top of native HTML, but React allows you to describe dynamic data in addition to static content.
React has three main design concepts that make it popular:
1 — Reusable, nested, stateful components
In React, we use components to describe the user interface. You can think of components as simple functions (in any programming language). We call the function with some input and give us some output. We can reuse functions as needed and build more complex functions from simple ones.
Components do exactly the same; We call the input when invoking the component “properties” and “state state,” and the output of the component is a description of the user interface (similar to HTML in a browser). We can reuse a single component across multiple user interfaces, and components can nest other components.
However, unlike pure functions, a full React component can have a private state to hold changing data.
2 — The nature of reactive updates
The word React itself means a simple explanation of this concept. When the state of a component (input) changes, so does the user interface it represents (output). This change in the user interface description also responds to the devices we use.
In the browser, we need to regenerate the HTML view in the Document Object Model (DOM). With React, we don’t have to worry about responding to these changes, or even managing when changes are applied to the browser; React makes state changes directly and automatically updates the DOM as needed.
3 — Virtual view in memory
In React, we use JavaScript to write HTML. We rely on the power of JavaScript to generate HTML from some data, rather than extending the power of HTML. Extended HTML is the choice of other JavaScript frameworks. For example, Angular extends HTML using loops, conditions, and other features.
When we receive data from the server (using Ajax in the background), we need more than HTML to process that data. Either use HTML with extended functionality, or use the capabilities of JavaScript itself to generate HTML. Both methods have their advantages and disadvantages. React opted for the latter.
In fact, there is one major advantage to using this approach; Using JavaScript to render HTML allows React to store a virtual representation of HTML (often called a virtual DOM) directly in memory. React uses the virtual DOM to render an HTML tree. Then, whenever the state data changes, we can update the tree representing the DOM. Instead of re-rendering the entire DOM, Instead, only the differences between the new tree and the previous one are written (because React keeps two versions in memory to compare the differences). This process is called Tree Reconciliation, and I think it’s the greatest invention in Web development since Ajax!
In the example below, we’ll focus on the third concept and see a simple example of the tree comparison process and the significant changes it makes. We’ll write the same HTML example twice, first using native Web apis and JavaScript, and then we’ll look at how React describes the same HTML tree.
To focus on illustrating this concept, instead of using components, we’ll use JavaScript timers to simulate changes in state data. We won’t use JSX either (using JSX in React greatly improves the efficiency of our code). In this example, we’ll use the React API directly to help you understand the concept better.
React scheduling algorithm example
To try this example, you need a browser and a code editor. It’s actually possible to use an online coding application, but I’ll use a local file and test it directly in a browser (no Web server required) :
We will write this example from scratch. Create a new directory and open it in your accustomed editor:
mkdir react-demo
cd react-demo
atom .
Copy the code
Create an index.html file in this directory and write a standard HTML template in it. We included a script.js file in the template and added a console.log statement to the script to test that our file correctly introduced:
index.html
<! DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>React Demo</title> </head> <body> <script src="script.js"></script> </body> </html>Copy the code
script.js
console.log('Included! ')Copy the code
Open the index.html file in your browser and make sure you can see that there is no problem with the empty template. You can see the console.log test message in the console that you put in script.js:
open index.html # Mac
explorer index.html # Windows
Copy the code
Now let’s introduce the React library file. We can use its CDN directly, copy the React and react-dom script tags and add them to index.html:
<script src="https://unpkg.com/react@latest/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@latest/dist/react-dom.js"></script>
Copy the code
We need to introduce two React libraries because React is implemented independently and can be used on other platforms. ReactDOM is used to render the interface described by React in the DOM:
Now let’s refresh the page and try printing React and ReactDOM on the console. We should see the global objects they expose:
With simple configuration, we now have access to the React and ReactDOM apis.
To dynamically insert HTML into a page, we need to declare a DOM tag as a container:
<div id="js"></div>
Copy the code
Then write code in our script.js script file to get the container:
Const jsContainer = document.getelementById ("js");Copy the code
We want to insert an HTML fragment simply by using the native innerHTML method:
InnerHTML = '<div class="demo"> Hello JS </div>';Copy the code
If all this works, you should see a “Hello JS” message in the page.
To illustrate our concepts more concisely, the code is kept that simple. Notice that all the methods we use are native JS methods. When you use React, you need to call the React API and interact with the DOM native API. In fact, the React source code inserts the DOM using innerHTML.
React acts as a proxy between us and the browser. We just tell React what to do and React will deal with the browser itself. The only cases where we need to use native JS directly are probably operations like getting a DOM container.
Create a new container with an ID like React.
<div id="react"></div>
Copy the code
Again, get the container in our script.js script file:
const reactContainer = document.getElementById("react");
Copy the code
Next we need to use the Render method in the ReactDOM library:
ReactDOM.render(
/* TODO: React's version of the HTML template */,
reactContainer
)
Copy the code
So what we’re going to do is, it’s really important for you to understand React. Remember we mentioned earlier that React uses JavaScript to write HTML.
We can generate a simple HTML interface by calling the React API
Instead of manipulating strings like before, React defines the content of the DOM by defining objects. The following methods generate the same content as in the native JS example:
ReactDOM.render(
React.createElement(
"div",
{ className: "demo" },
"Hello React"
),
reactContainer
);
Copy the code
The react. createElement method takes a number of arguments:
- The first is the name of the tag that generates the HTML, such as div
- And then the attributes of the tag, but we’re using objects here, for example {className: “demo”} will generate class=”demo”
- The third is the contents of the tag, such as the “Hello React” string in our example
We can now add a little more styling and look it up in the browser:
<style media="screen">
.demo {
border: 1px solid #ccc;
margin: 1em;
padding: 1em;
}
</style>
Copy the code
We now have two nodes, one created by the native DOM Web API and the other created by the React API. One of the main differences is that the React method uses a string to represent node content, whereas React uses a method to pass in objects to represent content.
No matter how complex our interface is, when we use React, all page elements are represented by objects passed in through the React. CreateElement method.
Let’s try something else. Let’s try nested HTML content. The native JS is the same as the string representation:
jsContainer.innerHTML = `
<div class="demo">
Hello JS
<input />
</div>
`;
Copy the code
React is also easy. We just need to change the third argument to the React. CreateElement method:
ReactDOM.render(
React.createElement(
"div",
{ className: "demo" },
"Hello React",
React.createElement("input")
),
reactContainer
);
Copy the code
If you look at this step, you might wonder. Does React complicate a simple problem? On the surface it looks that way, but there are reasons for doing so, read on:
Let’s add another tag that shows the timestamp:
jsContainer.innerHTML = `
<div class="demo">
Hello JS
<input />
<p>${new Date()}</p>
</div>
`;
Copy the code
With React, we pass in five arguments:
ReactDOM.render(
React.createElement(
"div",
{ className: "demo" },
"Hello React",
React.createElement("input"),
React.createElement(
"p",
null,
new Date().toString()
)
),
reactContainer
);
Copy the code
Now native JS and React still display the same content on the page.
From the examples so far, using React looks much more complex and difficult than the native method. So what’s so valuable about React that we can write in its API instead of writing native HTML? The question is not how to generate the page the first time, but how to update the content of the page afterwards.
Let’s demonstrate this with an example that lets the timestamp change from second to second.
The most straightforward way to do this is to execute the term setInterval per second:
const jsContainer = document.getElementById("js");
const reactContainer = document.getElementById("react");
const render = () => {
jsContainer.innerHTML = `
<div class="demo">
Hello JS
<input />
<p>${new Date()}</p>
</div>
`;
ReactDOM.render(
React.createElement(
"div",
{ className: "demo" },
"Hello React ",
React.createElement("input"),
React.createElement(
"p",
null,
new Date().toString()
)
),
reactContainer
);
}
setInterval(render, 1000);
Copy the code
Running our code, the timers in both nodes should now work automatically. However, if you try the native JS node now, you will find that input is not available because every second, the DOM element of the node is being rebuilt. You will notice that the input box for the Rect node works.
React also calls the Render method repeatedly, but in reality React only rerenders the part of the timer where the number has changed, leaving everything else unchanged and the input box working.
In the console, you can see the similarities and differences between the two nodes in detail. Everything on the original node is re-rendered, while React only updates the counter node.
React has an intelligent differential diff algorithm that generates only the parts of the DOM nodes that need to be re-rendered. This algorithm works because React’s virtual DOM technology stores the structure and content of the DOM in JS.
Using the virtual DOM, React keeps the last DOM version in memory, and when it has a new DOM version generated to the browser, the new DOM version will also be kept in memory, so React can calculate the difference between the new version and the old one (in our case, the difference is the timestamp paragraph).
React then instructs the browser to update only the calculated differences, not the entire DOM node. React will only add new “partial” updates to the browser, no matter how many times we rebuild our interface.
This approach not only improves efficiency, but also removes a lot of complexity from the way the user interface is updated. Having React to do all the calculations about whether we should update the DOM allows us to focus on thinking about our data (state) and the way we describe the user interface.
We then manage our data updates as needed, without worrying about the steps required to reflect those updates in the actual user interface in the browser (because we know React will do this automatically and in the most efficient way possible)!