by Ankita Masand
通过Ankita Masand
In this tutorial, I’ll first help you understand why Facebook felt the need to build a library called React. I’ll cover all the basic concepts that you’d need to create your first React app. This tutorial aims to explain React by clearly explaining its fundamentals like the use of JSX and ES6, building stateful & stateless components, React Elements, virtual DOM and the diffing algorithm.
在本教程中,我将首先帮助您理解为什么Facebook认为需要建立一个名为React的库。 我将介绍创建第一个React应用程序所需的所有基本概念。 本教程旨在通过清晰地解释其基本知识来解释React,例如使用JSX和ES6,构建有状态和无状态组件,React Elements,虚拟DOM和diffing算法 。
The web has evolved from just being a bunch of static HTML pages to reliable, interactive and performant applications. With the advent of AJAX, we can asynchronously load the entire application in parts.
网络已经从一堆静态HTML页面演变为可靠,交互式和高性能的应用程序。 随着AJAX的问世,我们可以分批异步加载整个应用程序。
Whenever there is a change in any part of the application due to real-time updates or user input, that part only is loaded asynchronously to reflect the updated state. This means that only the respective Document Object Model (DOM) container should be updated to reflect the changes to the client.
每当应用程序的任何部分由于实时更新或用户输入而发生更改时,该部分仅被异步加载以反映更新的状态。 这意味着仅应更新相应的文档对象模型( DOM )容器以将更改反映到客户端。
For example, consider the comments section on Facebook. The comments data fetched on initial load is appended to the DOM. Now, when you add a new comment, it makes an asynchronous request to the server to save this comment in the database, and update the DOM to reflect the current state.
例如,考虑Facebook上的评论部分。 初始加载时获取的注释数据将附加到DOM。 现在,当您添加新注释时,它将向服务器发出异步请求,以将该注释保存在数据库中,并更新DOM以反映当前状态。
Let’s get into the details of this example and understand how that would work. Let’s say that I have 20 comments in my comments array. The comments array is the source of truth, and it reflects the current state at any point in time. When the user adds a new comment, we need to modify this comments’ array once the new comment has been successfully added to the database. The comments array now holds 21 comments.
让我们进入这个例子的细节,并理解它是如何工作的。 假设我的评论数组中有20条评论。 评论数组是事实的来源,它反映了任何时间点的当前状态。 当用户添加新评论时,一旦新评论成功添加到数据库中,我们就需要修改此评论的数组。 注释数组现在包含21条注释。
Oh yeah, we also need to write code to update the DOM to reflect the current state (Assume we’re using Vanilla JavaScript or jQuery here. Cool stuff coming up next!). This means that the comments DOM container is subscribed to the comments array. It should be modified when there is any change in the comments array. We can safely say that the comments array is the model here, and the comments container is the view.
哦,是的,我们还需要编写代码来更新DOM以反映当前状态(假设我们在这里使用Vanilla JavaScript或jQuery。接下来会出现很酷的事情!)。 这意味着注释DOM容器已订阅了注释数组。 当注释数组有任何更改时,应对其进行修改。 我们可以肯定地说,这里的注释数组是模型,而注释容器是视图。
Let’s add something more to this — hundreds of div elements are subscribed to this comments model, which means that we need to write code to update each of these div
elements.
让我们为此添加更多内容-数百个div元素已订阅此注释模型,这意味着我们需要编写代码来更新每个div
元素。
function updateCommentsSubscriber (response) { commentsArr = [ ...response ] // commentsArr = ['Comment 1', 'Comment 2', ...] var firstDiv = document.getElementById('first') firstDiv.innerHTML = commentsArr.length var secondDiv = document.getElementById('second') secondDiv.innerHTML = commentsArr.toString() ...}
Sigh! Imagine if this happened at the scale at which Facebook operates. Whenever we have a new element that is subscribed to that model, we’d have to write code to make changes to that element. This approach is not scalable.
叹! 想象一下,这是否发生在Facebook经营的规模上。 每当我们有一个订阅该模型的新元素时,就必须编写代码来对该元素进行更改。 这种方法是不可扩展的。
Facebook dealt with the scalability and DOM slowness issue by building a library called React. React was first deployed on the Newsfeed section of Facebook in 2011, and then on Instagram in 2012. It was open-sourced in 2013 and has been applauded by the community worldwide ever since.
Facebook通过构建一个名为React的库来解决可伸缩性和DOM慢度问题。 React首先在2011年部署在Facebook的Newsfeed部分,然后在2012年部署在Instagram。它于2013年开源,此后一直受到全世界社区的称赞。
In this tutorial, we’ll build on the fundamentals of React. By the end of this tutorial, you should be able to write your first React app.
在本教程中,我们将基于React的基础知识。 在本教程结束时,您应该可以编写第一个React应用程序。
While I suggest a deep dive into each of these topics, please feel free to skip any of these if you’re already confident about it.
虽然我建议深入探讨每个主题,但如果您对此有信心,请随时跳过其中的任何一个。
React is a JavaScript library used for building user interfaces. It solves the scalability issue mentioned earlier by efficiently updating the DOM.
React是一个JavaScript库,用于构建用户界面 。 它通过有效地更新DOM解决了前面提到的可伸缩性问题。
One way to update the DOM is by manually putting in values in the respective DOM nodes, which is obviously slow and not scalable.
更新DOM的一种方法是通过在相应的DOM节点中手动输入值,这显然很慢且不可扩展。
Angular solves this problem by using data-binding. It binds the variables used in the view with their respective counterparts in the model. It automatically updates all the instances of a variable in a view when its respective value in a model changes.
Angular通过使用数据绑定解决了这个问题。 它将视图中使用的变量与模型中的相应变量绑定在一起。 当模型中变量的相应值更改时,它将自动更新视图中变量的所有实例。
On the other hand, React provides a different approach to solving this problem. It uses a technique called Reconciliation to evaluate the difference in the DOM representation at two points in time. It only updates the part that is changed. This will become clear once we get into the details of how React works. For now, let’s consider a simple example:
另一方面,React提供了解决此问题的不同方法。 它使用一种称为对帐的技术来评估两个时间点DOM表示形式的差异。 它仅更新已更改的零件。 一旦我们了解了React如何工作的细节,这将变得很清楚。 现在,让我们考虑一个简单的示例:
This goes into the HTML:
这进入HTML:
Put the below code in a JavaScript file:
将以下代码放入JavaScript文件中:
class HelloReact extends React.Component { render () { return ( Hello React! ) }}ReactDOM.render(, document.getElementById('app'))
The above example will print Hello React!
on the screen. HelloReact
is called a component in React. The render
method inside this component returns the DOM representation.
上面的示例将打印Hello React!
屏幕上。 HelloReact
在React中称为组件 。 该组件内部的render
方法返回DOM表示形式。
It’s not a coincidence that I wrote HTML in JavaScript.
nside render method is a JSX syntax. It lets us write HTML in JavaScript.
我用JavaScript编写HTML并非偶然。 The last statement does the work of rendering the 最后一条语句完成了在我们的 If we didn’t have JSX, you’d have to write the above JSX code as: 如果我们没有JSX,则必须将上面的JSX代码编写为: This can complicate things if you need to deal with nested elements. 如果您需要处理嵌套元素,这会使事情复杂化。 For example: 例如: And this is the JSX syntax for the above code: 这是上面代码的JSX语法: Writing JSX inside a React component gives a clear idea of what the component is going to render to the DOM. It looks clean and intuitive. 在React组件中编写JSX可以清楚地知道该组件将要呈现给DOM的内容。 它看起来干净直观。 If you’re already convinced of using JSX with React, continue reading to learn more. If not, React does allow you to use it without JSX. You can learn more about it here. 如果您已经确信将JSX与React一起使用,请继续阅读以了解更多信息。 如果没有,React允许您在没有JSX的情况下使用它。 您可以在此处了解更多信息。 JSX is just a JavaScript extension that allows writing HTML-like code: JSX只是一个JavaScript扩展,它允许编写类似HTML的代码: The expression inside the curly braces will be evaluated to the value of the variable 花括号内的表达式将被计算为变量 This would call the 这将调用 It is often the case that you need to render a DOM node only when a particular value has been set. 通常,只有在设置了特定值后才需要渲染DOM节点。 This can be achieved using JSX as: 这可以通过使用JSX来实现: The above example will greet a logged in user with his name and as Guest when a user is not logged in. 上面的示例将以未登录用户的身份和来宾身份欢迎已登录用户。 Please note that this conditional rendering is not similar to the show/hide scenario. Based on the value of the variable 请注意,此条件渲染与显示/隐藏场景不同。 基于变量 Let’s consider our comments example from above. Here, we have a comments array, and we need to render all of the comments in a DOM container. 让我们考虑上面的评论示例。 在这里,我们有一个comment数组,我们需要在DOM容器中呈现所有注释。 当构建React组件时, The above 上面的 Notice the use of 注意每个 The React library doesn’t understand JSX. It’s just used to make the developer’s job easier. So, what does React do when it comes across this weird HTML-like syntax in JavaScript code? React库不了解JSX。 它只是用来简化开发人员的工作。 那么,当JavaScript代码遇到类似HTML的怪异语法时,React会做什么? JSX is transpiled to JavaScript statements by the Babel plugin before React encounters them. Transpilation is the process of converting one source language to another. So, all that React sees is simple JavaScript statements. 在React遇到之前, Babel插件将JSX转换为JavaScript语句。 翻译是将一种源语言转换为另一种语言的过程 。 因此,React看到的只是简单JavaScript语句。 The simple JSX code from above 上面的简单JSX代码 gets transpiled to 被移植到 The first argument to the The second argument is used for specifying the attributes on the DOM node. In this case, we’re telling React that the 第二个参数用于指定DOM节点上的属性。 在这种情况下,我们告诉React节点的 Notice the use of 请注意,使用 The third argument carries information about the children of the DOM node. In this case, it is just plain text that will be added as 第三个参数携带有关DOM节点的子代的信息。 在这种情况下,纯文本将作为 The ES6 is the abbreviation for ECMAScript 6 or ECMAScript 2015. In this part, we’ll learn some common ES6 techniques that make developing React components an easier task. ES6是ECMAScript 6或ECMAScript 2015的缩写。在这一部分中,我们将学习一些通用的ES6技术,这些技术使开发React组件变得更加容易。 A variable declared inside a function can be used in the entire function, but not outside of it. 在函数内部声明的变量可以在整个函数中使用,但不能在其外部使用。 Let’s consider an example that will help us understand function-level scoping: 让我们考虑一个示例,该示例将帮助我们理解函数级作用域: The above 上面的 If you execute 如果执行 Notice that 注意, JavaScript follows function-level scoping, which means a variable declared in any statement inside a function is available throughout the function. So, JavaScript遵循函数级作用域,这意味着在函数内部的任何语句中声明的变量在整个函数中都可用。 因此,即使在 The Use 使用 You’ll get 您将获得 A variable declared using 使用 The second statement above displays an error since it’s not allowed to modify constant variables. 上面的第二条语句显示错误,因为不允许修改常量变量。 Consider an object, 考虑一个物体, If I need to use some of the keys from the above object, the conventional approach is: 如果需要使用上述对象中的某些键,则常规方法是: And with ES6: 对于ES6: The above statement creates local variables as 上面的语句创建了局部变量,如 Here, we’re destructuring the object to refer individual keys. If any of the keys wasn’t defined in the object, its value would be 在这里,我们要解构该对象以引用各个键。 如果未在对象中定义任何键,则其值将为 Here’s the old way of concatenating strings in JavaScript: 这是在JavaScript中串联字符串的旧方法: And here is the ES6 way: 这是ES6的方式: You can write the entire sentence in backticks without having to concatenate static text and variables in parts. Wrap the variables inside 您可以将整个句子写在反引号中,而不必将静态文本和变量分成多个部分。 将变量包装在 This one’s my favorite. Below is the old way of writing functions in JavaScript: 这是我的最爱。 下面是用JavaScript编写函数的旧方法: And this is the ES6 way of writing functions: 这是ES6编写函数的方式: Arrow functions follow this syntax: 箭头函数遵循以下语法: The above function 上面的函数 If a function body has more than one statement, wrap them in curly braces. 如果函数主体具有多个语句,则将它们括在花括号中。 Arrow functions behave a little different compared to normal functions when used with the 与 With ES6, we can wrap the relevant functions used for implementing a particular functionality inside a class. 使用ES6,我们可以将用于实现特定功能的相关功能包装在类中。 Let’s build a class to evaluate berries: 让我们建立一个评估浆果的类: We’ve wrapped the relevant berries methods inside the class 我们已经在 The statement 语句 The input passed to the Berries constructor is the 传递给Berries构造函数的输入是我们之前创建的 Now that we’ve learned most of the common ES6 techniques, we can use them in the following sections. 现在,我们已经学习了大多数常见的ES6技术,可以在以下各节中使用它们。 React Elements are the smallest units that represent the state of the DOM at any point in time. React Elements是表示任何时间点DOM状态的最小单位。 The browser doesn’t understand React. Like we saw earlier, JSX is converted to JavaScript statements for creating a DOM node. 浏览器不了解React。 如我们先前所见,JSX被转换为JavaScript语句以创建DOM节点。 With this statement: 带有以下语句: The These objects are called React Elements. 这些对象称为React Elements 。 They contain two important keys: 它们包含两个重要的键: The nested elements can be specified as the value of the 可以将嵌套元素指定为 React elements are immutable and are cheap to create. If there is any change in a React Element, its older instance is destroyed, and a newer one is created from scratch. React元素是不可变的,而且创建起来很便宜。 如果React Element中有任何更改,它将销毁其较旧的实例,并从头开始创建一个较新的实例。 However, the corresponding DOM node is not always destroyed to make room for a newer one. DOM operations are expensive, and hence they should be avoided at all possible instances. 但是,并不总是销毁相应的DOM节点以为新的节点腾出空间。 DOM操作非常昂贵,因此在所有可能的情况下都应避免使用它们。 ReactDOM does a great job here. It creates new React elements because creating them is cheap, however, it efficiently updates only the part of the real DOM node that is modified. ReactDOM在这里做得很好。 它创建新的React元素是因为创建它们很便宜,但是它仅有效地更新了实际DOM节点中已修改的部分。 React uses a diffing algorithm to find out what needs to be updated to the DOM. We’ll learn more about it in the Virtual DOM section. React使用差异算法来找出需要更新到DOM的内容。 我们将在“虚拟DOM”部分中了解更多信息。 Let’s go through what we’ve learned so far: 让我们回顾一下到目前为止所学到的内容: JSX is an HTML-like syntax that is used in React components. It’s just a representation of the DOM node and doesn’t actually append elements to the DOM. JSX是在React组件中使用的类似HTML的语法。 它只是DOM节点的表示,实际上并没有将元素附加到DOM。 The Babel plugin transpiles it to plain JavaScript statements as Babel插件将其作为 The Components are reusable classes that define a particular functionality. React follows a component-based structure. Each of the components that we define in React extends the basic functionalities of the native React Component. 组件是定义特定功能的可重用类。 React遵循基于组件的结构。 我们在React中定义的每个组件都扩展了本地React组件的基本功能。 Let’s create a simple React component for input text: 让我们为输入文本创建一个简单的React组件: Each of the React components has an implementation of the 每个React组件都有一个 The attributes — 传递给 React components maintain an internal state for handling the complexity based on various parameters. At the beginning of our component, we’ve initialized an object called React组件维护一个内部状态以根据各种参数处理复杂性。 在组件的开头,我们初始化了一个名为 The Let’s create a forms component that would import the Text component from above: 让我们创建一个表单组件,该组件将从上方导入Text组件: Form for basic details First, we’re importing the Text component. Notice how the Text component is included in the 首先,我们要导入文本组件。 请注意,Text组件如何包含在Forms组件的 When the Forms component is rendered, the 当窗体部件被呈现时, As mentioned earlier, React follows a Composition-based model. The bigger components can customize the components that are to be imported by sending in related props. 如前所述,React遵循基于组合的模型。 较大的组件可以通过发送相关道具来自定义要导入的组件。 Let’s modify the 让我们将上述Forms组件的 Form for basic details Notice how we’re passing 注意我们如何在Text组件中传递 We need to make changes to our Text component to accept these props. 我们需要对Text组件进行更改以接受这些道具。 Check out the changes in the 查看 The Forms组件传递的 The state variable manages the internal state of a component. It can be changed based on Network changes, user’s input or any scheduled updates. 状态变量管理组件的内部状态。 可以根据网络更改,用户输入或任何计划的更新来更改它。 Let’s say that we have our Berries Component and that its internal state is the 假设我们有浆果组件,其内部状态是上面定义的 If there's a change in the 如果 We’re not passing the entire 我们没有将整个 The The components defined above had their own state in place. However, we can also define Stateless components. 上面定义的组件具有自己的状态。 但是,我们也可以定义无状态组件。 These components are pure functions. They don’t modify the input passed to them. These are just representational components. 这些组件是纯函数。 他们不修改传递给他们的输入。 这些只是代表性的组成部分。 Let’s see an example of a stateless component: 让我们看一个无状态组件的示例: {size}<;/p> )} The only job of this component is to return a DOM representation for displaying the size of the Berries. 该组件的唯一工作是返回DOM表示形式以显示浆果的大小。 A React Component follows a certain lifecycle pattern. It goes through four important phases: React组件遵循一定的生命周期模式。 它经历了四个重要阶段: Let’s look into some of the methods that are invoked during these phases 让我们看一下在这些阶段中调用的一些方法 InitializationInitialize state and props. 初始化初始化状态和道具。 Mounting Mounting Updating 更新 Unmounting Unmounting This is a brief overview of the React Component Lifecycle. I’ll explain these methods in detail in my future articles. 这是React组件生命周期的简要概述。 我将在以后的文章中详细解释这些方法。 I mentioned the scalability problem earlier while introducing React. In this section, we’ll see how React efficiently solves this problem. 我在介绍React时提到了可扩展性问题。 在本节中,我们将看到React如何有效地解决这个问题。 From what you’ve learned so far, it’s clear that React doesn’t directly update the real DOM. All React knows is that DOM is nothing but a JavaScript object. This giant JavaScript object is called Virtual DOM. 从到目前为止所学的知识来看,很明显React不会直接更新真实的DOM。 React只知道DOM只是一个JavaScript对象。 这个巨大JavaScript对象称为Virtual DOM 。 If there is any change in the output of the 如果任何组件中 As mentioned earlier, React uses a technique called Reconciliation to evaluate the difference between the Real DOM and the Virtual DOM. 如前所述,React使用一种称为对帐的技术来评估实际DOM和虚拟DOM之间的差异。 Reconciliation is the action of making one view or belief compatible with another. And that’s exactly what ReactDOM does. It makes changes to the real DOM to make it compatible with the current state of the virtual DOM. React uses a diffing algorithm to evaluate the changes that are to be made to the real DOM. 和解是使一种观点或信念与另一种观点兼容的行为 。 而这正是ReactDOM所做的。 它对真实DOM进行更改,以使其与虚拟DOM的当前状态兼容。 React使用差异算法来评估要对真实DOM进行的更改。 It uses a heuristic algorithm that is based on two assumptions: 它使用基于两个假设的启发式算法: The Stable elements, or the elements that are not modified, are identified using a unique identifier called 使用称为 React first compares the type of the root element. If the type of root element is different in the real DOM and the virtual DOM, it destroys the real DOM and creates a new one. React首先比较根元素的类型。 如果实际DOM和虚拟DOM中根元素的类型不同,则会破坏实际DOM并创建一个新的DOM。 For example, if the root type in real DOM was 例如,如果实际DOM中的根类型为 This case deals with elements that are of the same type, but that have some differences in their property values. 这种情况处理的是相同类型的元素,但其属性值有所不同。 Consider this DOM node in real DOM: 考虑真实DOM中的此DOM节点: Now, consider the updated DOM node which is the output of a 现在,考虑更新的DOM节点,它是某些Component的 By comparing both of these nodes, React would know that only the className of the nodes is changed, and it would efficiently update just the value of the class in the real DOM. 通过比较这两个节点,React将知道仅节点的className被更改,并且它将有效地更新实际DOM中的类的值。 React recommends the use of the 如果要将相似的子项附加到特定的DOM节点,React建议使用 Let’s consider the example of a comments array: 让我们考虑一个注释数组的示例: The use of 在注释容器的子节点中使用 It does the tedious job of setting up a development server, handling the compilation of JSX down to JavaScript as discussed earlier, and it does a few more things. 如前所述,它完成了设置开发服务器,处理JSX到JavaScript的繁琐工作,并且还做了其他一些事情。 This installs the 这将在系统上全局安装 The command 命令 I hope you now have an idea of what React is and how to use it. 我希望您现在对React是什么以及如何使用它有所了解。 React components output DOM representation in the form of JSX. JSX is just syntactic sugar that is used to ease the development work. It gets transpiled to JavaScript statements in the form of React组件以JSX的形式输出DOM表示形式。 JSX只是语法糖,用于简化开发工作。 它得到transpiled在形式JavaScript语句 We learned about most of the common ES6 techniques like the use of 我们了解了大多数常见的ES6技术,例如 We learned that React follows a component-based pattern and how it uses Composition to create complex components using simpler ones. The Component uses 我们了解到,React遵循基于组件的模式,以及它如何使用Composition来使用简单的组件创建复杂的组件。 组件使用 In the next series of articles on React, I’ll cover the following topics in more detail: 在关于React的下一系列文章中,我将更详细地介绍以下主题: Getting started with React using 使用 Originally published at hashnode.com. 最初发布在hashnode.com上 。 翻译自: https://www.freecodecamp.org/news/a-beginners-guide-to-getting-started-with-react-c7f34354279e/> i
渲染方法是 JSX语法。 它使我们可以用JavaScript编写HTML。
HelloReact
component inside our app
container. In the following two sections, we'll dive deeper into JSX and ES6.app
容器内呈现HelloReact
组件的工作。 在以下两个部分中,我们将更深入地研究JSX和ES6。 JSX (JSX)
React.createElement("div", null, "Hello React!")
React.createElement("div", { className: "container" }, React.createElement("span", null, "Hello React!"), React.createElement("span", null, "I'm inside HelloReact Component"))
name
. You can even call functions inside JSX:name
的值。 您甚至可以在JSX内部调用函数: formatName
function and pass james.gosling
as the parameter to it. It'll render the value that is returned from the function formatName
.formatName
函数,并将james.gosling
作为参数传递给它。 它将呈现从函数formatName
返回的值。 条件语句 (Conditional Statements)
greetUser (userName) { if (isUserLoggedIn) { return
isUserLoggedIn
, only one of the two elements will be rendered to the DOM at a time.isUserLoggedIn
的值,一次只能将两个元素之一呈现给DOM。 使用地图功能渲染子节点 (Rendering Child Nodes using the map function)
map
is a native JavaScript function used for iterating the elements in an array. You can pass a custom iterator function as one of its arguments. Each of the elements in the array would be serving as input to this iterator function. map
will output an array based on the values returned during each iteration.map
是一个本机JavaScript函数,用于迭代数组中的元素。 您可以将自定义迭代器函数作为其参数之一传递。 数组中的每个元素都将用作此迭代器函数的输入。 map
将基于每次迭代期间返回的值输出一个数组。 map
comes handy when building React components. You can learn more about it here.map
变得很方便。 您可以在此处了解更多信息。 renderComments (commentsArr) { /* commentsArr would look similar to this structure below commentsArr = [{ id: 1, text: "I'm a comment!" }] */ return (
renderComments
method would return the result of the map
method. In this case, map
returns an array of DOM nodes.renderComments
方法将返回map
方法的结果。 在这种情况下, map
返回DOM节点数组。 key
with each div
element. We'll get into the details of using key
with DOM elements later. For now, it's just used as a way for uniquely identifying DOM elements.div
元素都使用key
。 稍后我们将详细介绍将key
与DOM元素一起使用的细节。 目前,它仅用作唯一标识DOM元素的方法。 将JSX编译为JavaScript (Compiling JSX to JavaScript)
React.createElement("div", { className: 'heading' }, "Hello React!")
createElement
method is defined on React.createElement
方法是在React上定义的。 createElement
method is the type of the DOM node that you'd like React to create for you. It can be div
, span
, p
, and so on.createElement
方法的第一个参数是您希望React为您创建的DOM节点的类型。 它可以是div
, span
, p
等。 className
of the node is heading
.className
是heading
。 className
instead of conventional class
attribute. In React, class
attribute is specified as className
to avoid conflicts with the existing attributes.className
代替了常规的class
属性。 在React中,将class
属性指定为className
以避免与现有属性冲突。 innerHTML
to the DOM nodeinnerHTML
添加到DOM节点 createElement
method is analogous to the document.createElement
method in JavaScript, but it outputs a React element. We'll get into the details of React Elements later.createElement
方法类似于JavaScript中的document.createElement
方法,但是它输出React元素。 稍后我们将详细介绍React Elements。 ES6 (ES6)
let
& const
(let
& const
)let
is used for declaring block-level variables, and const
is used for declaring constants. JavaScript follows a function-level scoping.let
用于声明块级变量,而const
用于声明常量。 JavaScript遵循功能级作用域 。 function pokemon (id) { //id = 12 if (id === 12) { var pokemonObj = { id: 12, name: 'butterfree', height: 11, weight: 22, abilities: [ { name: 'tinted-lens' } ] } } return pokemonObj }
pokemon
method takes id
as the parameter, and returns pokemonObj
if the id
is equal to 12
. Go ahead and run this function in your browser console.pokemon
方法将id
作为参数,如果id
等于12
,则返回pokemonObj
。 继续并在浏览器控制台中运行此功能。 pokemon(12)
, it prints the pokemonObj
as expected. However, if you execute pokemon(13)
, it doesn't display an error, and instead prints undefined
.pokemon(12)
,它将按预期打印pokemonObj
。 但是,如果执行pokemon(13)
,则不会显示错误,而是显示undefined
。 pokemonObj
gets defined in the if
construct, which means if the id
is not equal to 12, pokemonObj
should not be available in the context of the pokemon
function.pokemonObj
是在if
构造中定义的,这意味着如果id
不等于12,则pokemonObj
在pokemon
函数的上下文中不可用。 pokemonObj
is available even if it is declared inside if
block.if
块中声明了pokemonObj
, pokemonObj
仍然可用。 let
construct solves this problem as it lets us limit the scope of variables to block level.let
构造解决了这个问题,因为它允许我们将变量的范围限制为块级别。 let
for declaring the pokemonObj
and check the results:let
声明pokemonObj
并检查结果: function pokemon (id) { //id = 12 if (id === 12) { let pokemonObj = { id: 12, name: 'butterfree', height: 11, weight: 22, abilities: [ { name: 'tinted-lens' } ] } } return pokemonObj }
pokemonObj is not defined
, and that justifies the block-level scoping of variables declared using the let
construct.pokemonObj is not defined
,并证明使用let
结构声明的变量的块级作用域是合理的。 const
cannot be modified:const
声明的变量不能被修改: const POKEMON = 'butterfree' pokemon = 'pikachu'
对象分解 (Object Destructuring)
berries
, which are small fruit that can provide HP and status condition restoration, stat enhancement, and even damage negation when eaten by the Pokémon:berries
, berries
是一种小水果,当被神奇宝贝吃掉时,可以提供生命力和状态恢复,状态增强,甚至可以消除伤害: var berries = { id: 1, name: 'cheri', growth_time: '3', max_harvest: 5, natural_gift_power: 60, size: 20, smoothness: 25, soil_dryness: 15, natural_gift_type: { name: 'fire', url: 'https://pokeapi.co/api/v2/type/10/' }}
var id = berries.idvar name = berries.namevar growthTime = berries.growth_time
let { id, name, growth_time, max_harvest, natural_gift_power, size } = berries
id
, name
, growth_time
, max_harvest
, natural_gift_power
, and size
, and each of them will have the value corresponding to that in the berries
object. Isn't that cool?id
, name
, growth_time
, max_harvest
, natural_gift_power
和size
,并且每个变量的值都与berries
对象中的值相对应。 那不是很酷吗? undefined
.undefined
。 字符串模板 (String Templating)
var cheriDescription = "One of the berries is " + name + ". Its growth time is " + growth_time + ". Its size is " + size + ". Its Max Harvest is " + max_harvest.
let cheriDescription = `One of the berries is ${name}. Its growth time is ${growth_time}. Its size is ${size}. Its Max Harvest is ${max_harvest}.`
'${}'
. This looks a lot cleaner.'${}'
。 这看起来更干净。 箭头功能 (Arrow Functions)
function getBerrySize (berries) { return berries.size}
const getBerrySize = (berries) => berries.size
declaration
functionName
= (functionParams)
=> return res
ultdeclaration
functionName
= (functionParams)
=&g t; return res
t; return res
结果 getBerrySize
returns the size of the berry. Notice that we didn't write the word return
in the above arrow function. Use of return
is optional if the body of the arrow function has just one statement and it returns that statement.getBerrySize
返回berry的大小。 注意,我们没有在上面的箭头函数中写出单词return
。 如果arrow函数的主体只有一个语句,并且返回该语句,则使用return
是可选的。 this
construct. Learn more about this
and how the arrow functions behave differently when used with this
from my article here.this
结构一起使用时,箭头函数的行为与普通函数相比略有不同。 了解更多关于this
,以及如何与使用时的箭头功能表现不同this
从我的文章在这里 。 班级 (Classes)
class Berries { constructor (berries) { this.berries = berries } getSize () { return this.berries.size } getGrowthTime () { return this.berries.growth_time }}const cherries = new Berries(berries)cherries.getSize() // 20cherries.getGrowthTime() // 3
Berries
.Berries
类中包装了相关的berries方法。 const cherries = new Berries(berries)
instantiates the Berries class and create an Object of type Berries
.const cherries = new Berries(berries)
实例化Berries类并创建Berries
类型的Object。 berries
object we've created earlier. We can use methods defined in the Berries
class on this object.berries
对象。 我们可以在此对象的Berries
类中使用定义的方法。 React元素 (React Elements)
React.createElement("div", { className: 'heading' }, "Hello React!")
div
DOM node isn't yet appended to the DOM. The above statement is converted to plain JavaScript object as:div
DOM节点尚未附加到DOM。 上面的语句转换为普通JavaScript对象,如下所示: { type: 'div', props: { className: 'heading', children: 'Hello React!' }}
type
specifies the type of the DOM node. It can be div
, span
, p
, and so on.type
指定DOM节点的类型。 它可以是div
, span
, p
等。 props
describes the properties of that element. In this case, we have className
and children
.props
描述了该元素的属性。 在这种情况下,我们有className
和children
。 children
key.children
项键的值。 ReactDOM
does the work of converting these React Elements to actual DOM nodes and also updates them accordingly.ReactDOM
完成将这些React Elements转换为实际DOM节点的工作,并相应地对其进行更新。
React.createElement
.React.createElement
为普通JavaScript语句。 React.createElement
statements are further converted into JavaScript objects.React.createElement
语句进一步转换为JavaScript对象。 组件 (Components)
class Text extends React.Component { state = { value: '' } onChange = (e) => { this.setState({ value: e.target.value }) } render () { return ( ) }}export default Text
render
method. This method returns the DOM representation for that component. In our case, it returns an input
element. Remember, this input
element is not actually a DOM node. It's just a DOM representation.render
方法的实现。 此方法返回该组件的DOM表示形式。 在我们的例子中,它返回一个input
元素。 请记住,此input
元素实际上不是DOM节点。 这只是DOM表示。 text
, onChange
and value
that are passed to the input
element are called props in React. onChange
is an event handler that gets called whenever the value of the text in input box changes. props
in React are read-only.input
元素的属性( text
, onChange
和value
在React中称为props 。 onChange
是一个事件处理程序,只要输入框中的文本值发生更改,就会调用该事件处理程序。 React中的props
是只读的。 state
. This state variable handles the state of the Text Component. The state can be modified using the setState
method, as shown in the onChange
method defined above.state
的对象。 此状态变量处理文本组件的状态。 可以使用setState
方法修改状态,如上面定义的onChange
方法所示。 Text
component is an individual unit. It gets interesting when these components can be directly used in other complicated components. React follows a Composition
based model, which means importing smaller components to implement complex functionality. It composites different smaller components into a bigger component to make up for a working feature.Text
组件是一个单独的单元。 这些组件可以直接在其他复杂组件中使用时,会变得很有趣。 React遵循基于Composition
的模型,这意味着导入较小的组件以实现复杂的功能。 它将不同的较小组件组合为一个较大的组件,以弥补工作中的功能。 import Text from './text'class Forms extends React.Component { state = {} render () { return (
render
method of the Forms component.render
方法中。 f the
render method in the Text component.f the
呈现的文本组件方法。 有关
state
和props
更多信息 (More on state
and props
)render
method of the above Forms component asrender
方法修改为 render () { return (
type
props in the Text component.type
属性。 render
method:render
方法中的更改: render () { let { type } = this.props return ( )}
props
passed by the Forms component are available as an object in the Text Component. Notice how we're using the type
property in the Text component that was passed by the forms component.props
可以作为Text组件中的对象使用。 请注意,我们如何在Forms组件传递的Text组件中使用type
属性。 state
is nothing but a JavaScript object. It can be changed using the setState
method. The setState
method takes an object as an input. Whenever any value changes in a state, we only pass that value in the setState
method instead of passing the entire state object.state
不过是一个JavaScript对象。 可以使用setState
方法更改它。 setState
方法将一个对象作为输入。 每当状态中的任何值发生变化时,我们仅在setState
方法中传递该值,而不传递整个状态对象。 berries
object that we defined above.berries
对象。 growth_time
property of the berries
object, we can update it in the state as:berries
对象的growth_time
属性发生变化,我们可以将状态更新为: this.setState({ growth_time: new_growth_time })
berries
object to the setState
method. We're only passing the value that needs to be updated.berries
对象传递给setState
方法。 我们只是传递需要更新的值。 setState
method operates as an asynchronous function. Multiple state update calls are batched and invoked together at later intervals to deal with performance issues.setState
方法用作异步函数。 批处理多个状态更新调用,并在以后的时间间隔一起调用它们,以处理性能问题。 无状态组件 (Stateless Components)
const getBerrySize = (props) => { let { size } = props return (
组件生命周期 (Component Lifecycle)
componentWillMount
— this method is invoked just before the mounting occurs. It is called before the render
method. For setting the initial state & props, it’s recommended to use the constructor
in place of this method.componentWillMount
挂载发生前立即调用此方法。 在render
方法之前调用它。 为了设置初始状态和道具,建议使用constructor
代替此方法。 render
— this is the only required method in a class component. It returns the DOM representation at any point in time. It examines the value of state
and props
, and returns the updated DOM representation.render
—这是类组件中唯一需要的方法。 它在任何时间点返回DOM表示。 它检查state
和props
的值,并返回更新的DOM表示形式。 componentDidMount
— this method gets invoked immediately after the component is mounted. This is a good place to instantiate network requests to the server. Once the data is loaded from the server, you can call setState
method to invoke render
for updating the DOM nodes.componentDidMount
—挂载组件后立即调用此方法。 这是实例化对服务器的网络请求的好地方。 从服务器加载数据后,就可以调用setState
方法来调用render
来更新DOM节点。 componentWillReceiveProps
— if there is any change in props
, this method is called to render the updated state. It’s not recommended to use this method from React version 16 on.componentWillReceiveProps
—如果props
有任何更改,则调用此方法以呈现更新的状态。 不建议从React版本16开始使用此方法。 shouldComponentUpdate
— if this method returns true
, render
method is called to make room for the updated state
and props
.shouldComponentUpdate
-如果该方法返回true
, render
方法被调用,以腾出空间更新的state
和props
。 componentWillUpdate
— this method gets called immediately before render begins doing its work.componentWillUpdate
—在渲染开始工作之前立即调用此方法。 componentDidUpdate
— this method gets called once the updated state is rendered to the DOM.componentDidUpdate
—将更新的状态呈现给DOM后,将调用此方法。 componentWillUnmount
— this method is invoked just before the unmounting of a component. This is a good place to remove any subscriptions from the component.componentWillUnmount
—刚好在卸载组件之前调用此方法。 这是从组件中删除所有订阅的好地方。 虚拟DOM (Virtual DOM)
render
method in any of the components, the Virtual DOM accommodates these changes by destroying its older instance, and creating a newer one.render
方法的输出有任何更改,则虚拟DOM会通过销毁其旧实例并创建一个新实例来适应这些更改。
key
.key
的唯一标识符来标识Stable元素或未修改的元素。 不同类型的元素 (Elements of different types)
div
, and the one in virtual DOM was span
, the diffing algorithm would erase the entire div
container from the real DOM.div
,而虚拟DOM中的根类型为span
,则差异算法将从实际DOM中删除整个div
容器。 相同类型的DOM元素 (DOM Elements of the same type)
render
method of some Component:render
方法的输出: 确定子代在父容器中的位置 (Identifying the position of Children in the parent container)
key
prop if similar children are to be appended to a particular DOM node.key
prop。 commentsArr.map (comment => { return
key
in the child nodes of the comments container helps React to uniquely identify different comment nodes. If there is a change in any of the comment nodes, React would know which one to update based on the value of the key.key
有助于React唯一地标识不同的注释节点。 如果任何一个注释节点发生变化,React都会根据键的值知道要更新哪个。 使用
create-react-app
进行React入门 (Getting Started with React using create-react-app
)create-react-app
is a React Command Line interface tool that is used for creating the initial boilerplate for any react application.create-react-app
是一个React命令行界面工具,用于为任何React create-react-app
创建初始样板。 npm i create-react-app -g
create-react-app
node module globally on your system.create-react-app
节点模块。 create-react-app my-app
creates a react project inside themy-app
directory. Play around with the files and try building a smaller React component.create-react-app my-app
在my-app
目录中创建一个react项目。 试一试这些文件,然后尝试构建一个较小的React组件。 让我们回顾一下到目前为止所学到的东西 (Let’s recap what we’ve learned so far)
React.createElement
.React.createElement
。 let
and const
, Object Destructuring, Classes, Arrow Functions, and String Templating. These are used while writing React components.let
和const
的使用,对象解构,类,箭头函数和字符串模板化。 这些在编写React组件时使用。 state
and props
for handling internal state.state
和props
来处理内部状态。
create-react-app
create-react-app
开始使用React