react前端开发
by Samer Buna
通过Samer Buna
是的,React正在接管前端开发。 问题是为什么。 (Yes, React is taking over front-end development. The question is why.)
Update: This article is now part of my book “React.js Beyond The Basics”.
更新:本文现在是我的书《超越基础的React.js》的一部分。
Read the updated version of this content and more about React at jscomplete.com/react-beyond-basics.
在jscomplete.com/react-beyond-basics中阅读此内容的更新版本以及有关React的更多信息。
Here are a few reasons why React has become so popular so quickly:
以下是React如此Swift流行的一些原因:
- Working with the DOM API is hard. React basically gives developers the ability to work with a virtual browser that is more friendly than the real browser. React’s virtual browser acts like an agent between the developer and the real browser. 使用DOM API很难。 React基本上使开发人员能够使用比真实浏览器更友好的虚拟浏览器。 React的虚拟浏览器就像开发人员和实际浏览器之间的代理一样。
- React enables developers to declaratively describe their User Interfaces and model the state of those interfaces. This means instead of coming up with steps to describe transactions on interfaces, developers just describe the interfaces in terms of a final state (like a function). When transactions happen to that state, React takes care of updating the User Interfaces based on that. React使开发人员能够以声明方式描述其用户界面并为这些界面的状态建模。 这意味着开发人员无需提出描述接口上的事务的步骤,而只是按照最终状态(如函数)描述接口。 当事务发生这种状态时,React会根据该状态来更新用户界面。
- React is just JavaScript, there is a very small API to learn, just a few functions and how to use them. After that, your JavaScript skills are what make you a better React developer. There are no barriers to entry. A JavaScript developer can become a productive React developer in a few hours. React只是JavaScript,有一个非常小的API需要学习,只有几个函数以及如何使用它们。 之后,您JavaScript技能将使您成为更好的React开发人员。 没有进入障碍。 JavaScript开发人员可以在几个小时内成为高效的React开发人员。
But there’s a lot more to it than just that. Let’s attempt to cover all the reasons behind React’s rising popularity. One reason is its Virtual DOM (React’s reconciliation algorithm). We’ll work through an example to show the actual practical value of having such an algorithm at your command.
但是,不仅限于此。 让我们尝试介绍React越来越受欢迎的所有原因。 原因之一是其虚拟DOM(React的对帐算法)。 我们将通过一个示例来说明在您的命令中使用这种算法的实际实用价值。
React’s official definition states that it’s a JavaScript library for building User Interfaces. It’s important to understand the two different parts of this definition:
React的官方定义指出它是一个用于构建User Interfaces的JavaScript库 。 了解此定义的两个不同部分很重要:
React is a JavaScript library. It’s not a framework. It’s not a complete solution and we’ll often need to use more libraries with React to form any solution. React does not assume anything about the other parts in any full solution. It focuses on just one thing, and on doing that thing very well.
React是一个JavaScript库 。 这不是一个框架。 这不是一个完整的解决方案,我们经常需要在React中使用更多的库来形成任何解决方案。 在任何完整的解决方案中,React都不假设其他部分。 它只关注一件事,并且非常擅长于做那件事。
The thing that React does really well is the second part of the definition: building User Interfaces. A User Interface is anything we put in front of users to have them interact with a machine. User Interfaces are everywhere, from the simple buttons on a microwave to the dashboard of a space shuttle. If the device we’re trying to interface can understand JavaScript, we can use React to describe a User Interface for it.
React确实做得很好的事情是定义的第二部分: 构建用户界面 。 用户界面是我们摆在用户面前以使其与机器交互的任何东西。 用户界面无处不在,从微波炉上的简单按钮到航天飞机的仪表板。 如果我们尝试连接的设备可以理解JavaScript,则可以使用React为其描述用户界面。
Since Web browsers understand JavaScript, we can use React to describe Web User Interfaces. I like to use the word describe here because that’s what we basically do with React, we just tell it what we want and React will build the actual User Interfaces, on our behalf, in the Web browser. Without React or similar libraries, we would need to manually build User Interfaces with native Web APIs and JavaScript.
由于Web浏览器了解JavaScript,因此我们可以使用React来描述Web用户界面。 我喜欢在这里使用“ 描述 ”一词,因为这基本上就是我们对React所做的事情,我们只是告诉我们想要什么,React将代表我们在Web浏览器中构建实际的用户界面。 如果没有React或类似的库,我们将需要使用本机Web API和JavaScript手动构建用户界面。
When you hear the statement that “React is declarative,” this is exactly what it means, we describe User Interfaces with React and tell it what we want (not how to do it). React will take care of the “how” and translate our declarative descriptions (which we write in the React language) to actual User Interfaces in the browser. React shares this simple declarative power with HTML itself, but with React, we get to be declarative for HTML interfaces that represent dynamic data, not just static data.
当您听到“ React是声明性”的说明时,这正是它的含义,我们使用React描述用户界面,并告诉我们我们想要什么(而不是方法)。 React将照顾“如何”,并将我们的声明性描述(我们用React语言编写)翻译成浏览器中的实际用户界面。 React与HTML本身具有这种简单的声明性功能,但是通过React,我们可以对表示动态数据(不仅是静态数据)HTML接口进行声明。
React has three main design concepts that drive its popularity:
React具有三个主要的设计概念来推动其流行:
1-使用可重用,可组合和有状态的组件 (1 — The use of reusable, composable, and stateful components)
In React, we describe User Interfaces using components. You can think of components as simple functions (in any programming language). We call functions with some input and they give us some output. We can reuse functions as needed and compose bigger functions from smaller ones.
在React中,我们描述了使用组件的用户界面。 您可以将组件视为简单功能(使用任何编程语言)。 我们用一些输入调用函数,它们给我们一些输出。 我们可以根据需要重用函数,并从较小的函数组成较大的函数。
Components are exactly the same; we call their input “properties” and “state”, and a component output is a description of a User Interface (which is similar to HTML for browsers). We can reuse a single component in multiple User Interfaces, and components can contain other components.
组件完全相同; 我们将其输入称为“属性”和“状态”,组件输出是对用户界面的描述(类似于浏览器HTML)。 我们可以在多个用户界面中重用单个组件,而组件可以包含其他组件。
Unlike pure functions however, a full React component can have a private state to hold data that may change over time.
但是,与纯函数不同,完整的React组件可以具有私有状态来保存随时间变化的数据。
2-React性更新的性质 (2 — The nature of reactive updates)
React’s name is the simple explanation for this concept. When the state of a component (the input) changes, the User Interface it represents (the output) changes as well. This change in the description of the User Interface has to be reflected in the device we’re working with.
React的名字就是这个概念的简单解释。 当组件(输入)的状态更改时,它表示的用户界面(输出)也更改。 用户界面说明中的更改必须反映在我们正在使用的设备中。
In a browser, we need to regenerate the HTML views in the Document Object Model (DOM). With React, we do not need to worry about how to reflect these changes, or even manage when to take changes to the browser; React will simply react to the state changes and automatically update the DOM when needed.
在浏览器中,我们需要在文档对象模型(DOM)中重新生成HTML视图。 使用React,我们无需担心如何反映这些更改,甚至不必担心何时对浏览器进行更改。 React只会对状态变化做出React ,并在需要时自动更新DOM。
3 —内存中视图的虚拟表示 (3 — The virtual representation of views in memory)
With React, we write HTML using JavaScript. We rely on the power of JavaScript to generate HTML that depends on some data, rather than enhancing HTML to make it work with that data. Enhancing HTML is what other JavaScript frameworks usually do. For example, Angular extends HTML with features like loops, conditionals, and others.
使用React,我们使用JavaScript编写HTML。 我们依靠JavaScript的功能来生成依赖于某些数据HTML,而不是增强HTML以使其与该数据一起使用。 增强HTML是其他JavaScript框架通常要做的事情。 例如,Angular使用循环,条件等功能扩展了HTML。
When we receive just the data from the server (in the background, with AJAX), we need something more than HTML to work with that data. It’s either using an enhanced HTML, or using the power of JavaScript itself to generate the HTML. Both approaches have advantages and disadvantages. React embraces the latter one, with the argument that the advantages are stronger than the disadvantages.
当我们仅从服务器(在后台,使用AJAX)接收数据时,除了HTML之外,我们还需要其他一些东西来处理这些数据。 它要么使用增强HTML,要么使用JavaScript本身的功能来生成HTML。 两种方法都有优点和缺点。 React拥护后者,理由是优势强于弊。
In fact, there is one major advantage that can make the case for this approach by itself; using JavaScript to render HTML makes it easy for React to keep a virtual representation of HTML in memory (which is commonly known as The Virtual DOM). React uses the Virtual DOM to render an HTML tree virtually first, and then, every time a state changes and we get a new HTML tree that needs to be taken to the browser’s DOM, instead of writing the whole new tree React will only write the difference between the new tree and the previous tree (since React has both trees in memory). This process is known as Tree Reconciliation, and I think, it is the best thing that has happened in Web Development since AJAX!
实际上,有一个主要优势可以单独为这种方法辩护。 使用JavaScript渲染HTML可以使React轻松地在内存中保留HTML的虚拟表示形式(通常称为The Virtual DOM )。 React使用虚拟DOM首先虚拟地渲染HTML树,然后,每次状态改变时,我们都会获得一个需要带入浏览器DOM的新HTML树,而不是编写整个新树,React只会编写新树和前一棵树之间的差异(因为React在内存中有两棵树)。 这个过程称为树协调 ,我认为,这是自AJAX以来Web开发中发生的最好的事情!
In the following example, we’ll focus on this last concept and see a simple practical example of the tree reconciliation process and the big difference it makes. We’ll write the same HTML example twice, first using native Web APIs and vanilla JavaScript, and then we’ll see how to describe the same HTML tree with React.
在下面的示例中,我们将专注于最后一个概念,并看到一个简单的树协调过程的实际示例及其带来的巨大差异。 我们将编写两次相同HTML示例,首先使用本机Web API和Vanilla JavaScript,然后再看如何使用React来描述同一HTML树。
To purely focus on this last concept, we will not be using components, and we will mock a state change operation using a JavaScript timer. We are also not going to use JSX, although using JSX will make for a much simpler code. I use JSX all the time when I write React, but working with React API directly in this example will hopefully make you understand this concept much better.
仅关注最后一个概念,我们将不使用组件,而将使用JavaScript计时器模拟状态更改操作。 我们也不会使用JSX,尽管使用JSX会使代码简单得多。 编写React时,我一直都在使用JSX,但是在此示例中直接使用React API有望使您更好地理解这个概念。
React的对帐算法示例 (React’s reconciliation algorithm example)
To follow along with this example, you need a browser and a code editor. You can actually use an online coding playground, but I’ll use local files and test them directly in a browser (we don’t need a web server):
要继续执行此示例,您需要一个浏览器和一个代码编辑器。 您实际上可以使用在线编码游乐场,但是我将使用本地文件并在浏览器中直接对其进行测试(我们不需要Web服务器):
We’ll start this example from scratch. Create a new directory, and launch your favorite editor there:
我们将从头开始这个例子。 创建一个新目录,并在其中启动您喜欢的编辑器:
mkdir react-democd react-demoatom .
Create an index.html
file in that directory, and put a standard HTML template in there. Include in that template a script.js
file and put a console.log
statement in that script to test that the include works:
在该目录中创建一个index.html
文件,然后在其中放置一个标准HTML模板。 在该模板中包含一个script.js
文件,并在该脚本中放入console.log
语句以测试该包含是否有效:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>React Demo</title>
</head>
<body>
<script src="script.js"></script>
</body>
</html>
Open the index.html
file in your browser and make sure you can see the empty template without problems, and that you can see in the Console dev-tools tab the console.log
test message that you put in script.js
:
在浏览器中打开index.html
文件,并确保可以看到没有问题的空模板,并且可以在Console dev-tools选项卡中看到放在script.js
的console.log
测试消息:
open index.html # On Mac
explorer index.html # On Windows
Now, let’s bring in the React library itself, which we can include from the Reactjs website. Copy both the react
and react-dom
scripts, and include them in index.html
:
现在,让我们引入React库本身,我们可以从Reactjs网站中包含它。 复制react
和react-dom
脚本,并将它们包括在index.html
:
<script src="https://unpkg.com/react@15/dist/react.js"></script> <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
We’re including two different scripts here for an important reason: The React
library itself can be used without a browser. To use React with a browser, we need the ReactDOM
library.
出于重要原因,我们在此处包括两个不同的脚本: React
库本身可以在没有浏览器的情况下使用。 要在浏览器中使用React,我们需要ReactDOM
库。
When we refresh the browser now, we should see both React
and ReactDOM
available on the global scope:
现在刷新浏览器时,应该在全局范围内看到React
和ReactDOM
可用:
With this simple setup, we can now access both React
and ReactDOM
APIs, and of course, we also have access to the native Web APIs and JavaScript which we are going to use first.
通过此简单的设置,我们现在可以访问React
和ReactDOM
API,当然,我们还可以访问我们将首先使用的本机Web API和JavaScript。
To insert HTML dynamically in the browser we can simply use pure JavaScript and the DOM Web API itself. Let’s create a div
element to host our JavaScript HTML content and give it the id "js"
. In the body element of index.html
, right before the script
tag, add:
要在浏览器中动态插入HTML,我们可以简单地使用纯JavaScript和DOM Web API本身。 让我们创建一个div
元素来托管我们JavaScript HTML内容,并为其指定id "js"
。 在index.html
的body元素中,在script
标记之前,添加:
<div id="js"></div>
Now in script.js
, let's grab this new div
element by its id and put it in a constant. Let's name this constant jsContainer
. We can use document.getElementById
to grab the div
from HTML:
现在在script.js
,让我们通过其id来获取这个新的div
元素,并将其放入一个常量中。 让我们将此常量jsContainer
。 我们可以使用document.getElementById
从HTML抓取div
:
jsContainer.innerHTML = `
<div class="demo">
Hello JS
</div>
`;
To control the content of this div
, we can use the innerHTML
setter call on the div
element directly. We can use this call to supply any HTML template that we want inserted in the DOM. Let's insert a div
element with a class of "demo" and the string "Hello JS" as its content:
要控制此div
的内容,我们可以直接在div
元素上使用innerHTML
setter调用。 我们可以使用此调用来提供要插入DOM的任何HTML模板。 让我们插入一个带有“ demo”类和字符串“ Hello JS”作为内容的div
元素:
jsContainer.innerHTML = ` <div class="demo"> Hello JS </div>`;ReactDOM.render(
/* TODO: React's version of the HTML template */,
reactContainer
)
Make sure this works in the browser. You should see the “Hello JS” line on the screen now.
确保这在浏览器中有效。 您现在应该在屏幕上看到“ Hello JS”行。
This demo div is our User Interface so far. It’s a very simple one. We just output a text for the user to see.
到目前为止,此演示div是我们的用户界面。 这是一个非常简单的过程。 我们只输出文本供用户查看。
Both document.getElementById
and element.innerHTML
are actually part of the native DOM Web API. We are communicating with the browser directly here using the supported APIs of the Web platform. When we write React code, however, we use the React API instead, and we let React communicate with the browser using the DOM Web API.
document.getElementById
和element.innerHTML
实际上都是本机DOM Web API的一部分。 我们正在使用Web平台支持的API在此处直接与浏览器进行通信。 但是,在编写React代码时,我们改用React API,然后让React使用DOM Web API与浏览器进行通信。
React acts like our agent for the browser, and we mostly need to communicate with just React, our agent, and not the browser itself. I say mostly because there are cases where we still need to communicate with the browser, but those are rare.
React的作用就像我们对浏览器代理 ,我们主要是需要与刚React过来,我们的代理商进行沟通,而不是浏览器本身。 我说这主要是因为在某些情况下我们仍然需要与浏览器进行通信,但是这种情况很少见。
To create the exact same User Interface that we have so far but with React API this time, let’s create another div
element and give it an id of "react"
. In index.html
, right under the div#js
element, add:
为了创建与目前为止完全相同的用户界面,但是这次使用React API,让我们创建另一个div
元素,并将其id设置为"react"
。 在div#js
元素正下方的index.html
,添加:
<div id="react"></div>
Now, in script.js
, create a new container constant for the new div
:
现在,在script.js
,为新的div
创建一个新的容器常量:
const reactContainer = document.getElementById("react");
This container will be the only call we make to the native web API. ReactDOM needs this container to know where to host our application in the DOM.
该容器将是我们对本地Web API的唯一调用。 ReactDOM需要此容器来知道将应用程序托管在DOM中的何处。
With the react container identified, we can now use the ReactDOM library to render
React's version of the HTML template to this container:
确定了react容器后,我们现在可以使用ReactDOM库render
ReactHTML模板版本render
到此容器:
ReactDOM.render(
/* TODO: React's version of the HTML template */,
reactContainer
)
What we’re going to do next is your first milestone in truly understanding the React library. Remember when I told you that with React we write HTML using JavaScript? This is exactly what we are going to do next.
我们接下来要做的是您真正了解React库的第一个里程碑。 还记得我告诉过您的问题,我们使用React使用JavaScript编写HTML吗? 这正是我们接下来要做的。
To write our simple HTML User Interface, we are going to use JavaScript calls to React API, and by the end of the example you’ll have a better picture about the reason for doing so.
为了编写简单HTML用户界面,我们将使用对React APIJavaScript调用,并且到示例结束时,您将对这样做的原因有更好的了解。
Instead of working with strings (as we did in the native JavaScript example above), in React, we work with objects. Any HTML string will be represented as an object using a React.createElement
call (which is the core function in the React API).
在React中,我们没有使用字符串(就像我们在上面的原生JavaScript示例中所做的那样),而是使用objects 。 任何HTML字符串都将使用React.createElement
调用(这是React API中的核心功能)表示为一个对象。
Here’s the equivalent HTML User Interface we have so far with React:
这是到目前为止,React具备的等效HTML用户界面:
ReactDOM.render(
React.createElement(
"div",
{ className: "demo" },
"Hello React"
),
reactContainer
);
React.createElement
has many arguments:
React.createElement
有很多参数:
The first argument is the HTML tag, which is
div
in our example.第一个参数是HTML标记,在我们的示例中为
div
。The second argument is an object that represents any attributes we want this tag to have. To match the native JS example we used
{ className: "demo" }
which translates toclass="demo"
. Note how we usedclassName
instead ofclass
in the attributes because with React it's all JavaScript that matches the Web API, not HTML itself.第二个参数是一个对象,代表我们希望此标签具有的所有属性。 为了匹配本地JS示例,我们使用了
{ className: "demo" }
,它转换为class="demo"
。 注意我们如何在属性中使用className
而不是class
,因为使用React时,所有JavaScript都与Web API匹配,而不是HTML本身。- The third argument is the content of the element. We’ve put a “Hello React” string in there. 第三个参数是元素的内容。 我们在其中放置了一个“ Hello React”字符串。
We can test this now. The browser should render both “Hello JS” and “Hello React”. Let’s style the demo divs as a box, using this CSS, just so that we can visually split the screen. In index.html
:
我们现在可以对此进行测试。 浏览器应同时呈现“ Hello JS”和“ Hello React”。 让我们使用此CSS将演示div设置为一个框样式,以使我们可以在视觉上拆分屏幕。 在index.html
:
<style media="screen">
.demo {
border: 1px solid #ccc;
margin: 1em;
padding: 1em;
}
</style>
We now have two nodes, one being controlled with the DOM Web API directly, and another being controlled with the React API (which in turn uses the DOM Web API). The only major difference between the ways we are building these two nodes in the browser is that in the JS version we used a string to represent the content, while in the React version we used pure JavaScript calls and represented the content with an object instead of a string.
现在,我们有两个节点,一个节点直接由DOM Web API控制,另一个节点由React API(反过来使用DOM Web API)控制。 我们在浏览器中构建这两个节点的方式之间的唯一主要区别在于,在JS版本中,我们使用字符串表示内容,而在React版本中,我们使用纯JavaScript调用,并使用对象而不是对象来表示内容一个字符串。
No matter how complicated the HTML User Interface is going to get, when using React, every HTML element will be represented with a JavaScript object using a React.createElement
call.
不管HTML用户界面会变得多么复杂,使用React时,每个HTML元素都将通过React.createElement
调用由一个JavaScript对象表示。
Let’s now add some more features to our simple User Interface. Let’s add a text box to read input from the user.
现在让我们在简单的用户界面中添加更多功能。 让我们添加一个文本框以读取用户的输入。
To nest elements in our HTML template, it’s straight forward in the JS version because it’s just HTML. For example, to make the demo div
render an <input/>
element, we simply add it to the content:
为了将元素嵌套在我们HTML模板中,在JS版本中很简单,因为它只是HTML。 例如,要使demo div
呈现一个<input/>
元素,我们只需将其添加到内容中:
jsContainer.innerHTML = `
<div class="demo">
Hello JS
<input />
</div>
`;
We can do the same with React by adding more arguments after the 3rd argument for React.createElement
. To match what we did in the native JS example, we can add a 4th argument that is another React.createElement
call that renders an input
element (remember, every HTML element is an object):
通过在React.createElement
的第3个参数之后添加更多参数,我们可以对React进行React.createElement
。 为了匹配我们在本机JS示例中所做的工作,我们可以添加第4个参数,这是另一个React.createElement
调用,该调用呈现一个input
元素(请记住,每个HTML元素都是一个对象):
ReactDOM.render(
React.createElement(
"div",
{ className: "demo" },
"Hello React",
React.createElement("input")
),
reactContainer
);
At this point, if you’re questioning what we’re doing and thinking “this is complicating a simple process”, you are totally right! But there is a very good reason for what we’re doing. Keep reading.
在这一点上,如果您质疑我们在做什么,并认为“这使一个简单的过程变得复杂”,那是完全正确的! 但是我们正在做的事情有一个很好的理由。 继续阅读。
Let’s also render a timestamp in both versions. In the JS version, let’s put the timestamp in a paragraph element. We can use a call to new Date()
to display a simple timestamp:
我们还要在两个版本中都渲染一个时间戳。 在JS版本中,让我们将时间戳记放在段落元素中。 我们可以使用对new Date()
的调用来显示简单的时间戳:
jsContainer.innerHTML = `
<div class="demo">
Hello JS
<input />
<p>${new Date()}</p>
</div>
`;
To do the same in React, we add a 5th argument to the top-level div
element. This new 5th argument is another React.createElement
call, this time using a p
tag, with no attributes, and the new Date()
string for content:
为了在React中做同样的事情,我们在顶层div
元素中添加了第5个参数。 这个新的第5个参数是另一个React.createElement
调用,这次使用p
标签,没有属性,并且使用new Date()
字符串作为内容:
ReactDOM.render(
React.createElement(
"div",
{ className: "demo" },
"Hello React",
React.createElement("input"),
React.createElement(
"p",
null,
new Date().toString()
)
),
reactContainer
);
Both JS and React versions are still rendering the exact same HTML in the browser.
JS和React版本仍然在浏览器中呈现完全相同HTML。
As you can see, so far, using React is actually a lot harder than the simple and familiar native way. What is it that React does so well that’s worth giving up the familiar HTML and having to learn a new API to write what can be simply written in HTML? The answer is not about rendering the first HTML view, it’s about what we need to do to update any existing view in the DOM.
如您所见,到目前为止,使用React实际上比简单和熟悉的本机方法难得多。 React的出色表现是什么,值得放弃熟悉HTML,而必须学习新的API来编写可以简单地用HTML编写的东西? 答案不是关于呈现第一个HTML视图,而是关于我们需要做什么以更新DOM中的任何现有视图。
So, let’s do an update operation on the DOM we have so far. Let’s simply make the timestamp tick every second.
因此,让我们对到目前为止的DOM进行更新操作。 让我们简单地使时间戳每秒钟滴答一声。
We can easily repeat a JavaScript function call in a browser using the setInterval
Web timer API. So, let's put all of our DOM manipulations for both JS and React versions in a function, call it render
, and use it in a setInterval
call to make it repeat every second.
我们可以使用setInterval
Web计时器API在浏览器中轻松地重复JavaScript函数调用。 因此,让我们将针对JS和React版本的所有DOM操作放入一个函数中,将其称为render
,并在setInterval
调用中使用它以使其每秒重复一次。
Here’s the full final code in script.js
:
这是script.js
完整的最终代码:
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);
When we refresh the browser now, the timestamp string should be ticking every second in both versions. We are now updating our User Interface in the DOM.
现在,当我们刷新浏览器时,两个版本中的时间戳字符串都应该每秒滴答一声。 现在,我们正在DOM中更新用户界面。
This is the moment when React will potentially blow your mind. If you try to type something in the text box of the JS version, you won’t be able to. This is very much expected because we’re basically throwing away the whole DOM node on every tick and regenerating it. However, if you try to type something in the text box that’s rendered with React, you can certainly do so!
这是React可能会打动您的时刻。 如果尝试在JS版本的文本框中键入内容,则将无法进行输入。 这是非常期望的,因为我们基本上是在每个刻度上丢弃整个DOM节点并重新生成它。 但是,如果您尝试在使用React渲染的文本框中键入内容,那么您当然可以这样做!
Although the whole React rendering code is within our ticking timer, React is changing only the timestamp paragraph and not the whole DOM node. This is why the text input box was not regenerated and we were able to type in it.
尽管整个React呈现代码都在我们的滴答计时器内,但是React仅更改了timestamp段落,而不更改了整个DOM节点。 这就是为什么未重新生成文本输入框,而我们能够键入它的原因。
You can see the different ways we’re updating the DOM visually if you inspect the two DOM nodes in a Chrome dev tools elements panel. The Chrome div tools highlights any HTML elements that get updated. You’ll see how we are regenerating the whole “js” div on every tick, while React is smartly only regenerating the paragraph with the timestamp string.
如果您在Chrome开发者工具元素面板中检查两个DOM节点,则可以看到以可视方式更新DOM的不同方式。 Chrome div工具突出显示所有已更新HTML元素。 您将看到我们如何在每个刻度上重新生成整个“ js” div,而React巧妙地仅使用时间戳字符串重新生成该段落。
React has a smart diffing algorithm that it uses to only regenerate in its DOM node what actually needs to be regenerated while it keeps everything else as is. This diffing process is possible because of React’s virtual DOM and the fact that we have a representation of our User Interface in memory (because we wrote in JavaScript).
React有一个智能差异算法,它仅用于在其DOM节点中重新生成实际需要重新生成的内容,同时将其他所有内容保持不变。 由于React的虚拟DOM以及我们在内存中具有用户界面的表示形式(因为我们用JavaScript编写),因此可以进行这种区分过程。
Using the virtual DOM, React keeps the last DOM version in memory and when it has a new DOM version to take to the browser, that new DOM version will also be in memory, so React can compute the difference between the new and the old versions (in our case, the difference is the timestamp paragraph).
使用虚拟DOM,React将最后一个DOM版本保留在内存中,并且当它具有要发送到浏览器的新DOM版本时,该新DOM版本也将存在于内存中,因此React可以计算新版本和旧版本之间的差异(在我们的示例中,区别是时间戳记段)。
React will then instruct the browser to update only the computed diff and not the whole DOM node. No matter how many times we regenerate our interface, React will take to the browser only the new “partial” updates.
然后,React将指示浏览器仅更新计算的差异,而不更新整个DOM节点。 无论我们重新生成界面多少次,React都只会将新的“部分”更新带给浏览器。
Not only is this method a lot more efficient, but it also removes a big layer of complexity for the way we think about updating User Interfaces. Having React do all the computations about whether we should update the DOM or not enables us to focus on thinking about our data (state) and the way to describe a User Interface for it.
这种方法不仅效率更高,而且为我们考虑更新用户界面的方式也消除了很大的复杂性。 让React对是否应该更新DOM进行所有计算,使我们能够专注于思考数据(状态)以及为它描述用户界面的方式。
We then manage the updates on our data as needed without worrying about the steps needed to reflect these updates on the actual User Interface in the browser (because we know React will do exactly that and it will do that in an efficient way!)
然后,我们根据需要管理数据更新,而无需担心将这些更新反映在浏览器中的实际用户界面上所需的步骤(因为我们知道React会做到这一点,并且会以高效的方式做到这一点!)
Thanks for reading! You can view the source code of my demo here, and you can see the demo running here.
谢谢阅读! 您可以在此处查看演示的源代码,也可以在此处查看运行的演示。
Learning React or Node? Checkout my books:
学习React还是Node? 结帐我的书:
react前端开发