2018 react 大会_2018年React.js全面指南

2018 react 大会

Components are the building blocks of React. If you’re coming from an Angular background, components are very similar to Directives. If you’re coming from a different background, they’re essentially widgets or modules.

组件是React的基础。 如果您来自Angular背景,则组件与指令非常相似。 如果您来自不同的背景,它们本质上就是小部件或模块。

You can think of a component as a collection of HTML, CSS, JS, and some internal data specific to that component. I like to think of React components as the Kolaches of the web. They have everything you need, wrapped in a delicious composable bundle.

您可以将组件视为HTML,CSS,JS以及该组件特定的一些内部数据的集合。 我喜欢把React的组分作为Kolaches网络的价值。 它们具有您需要的所有东西,并包装在可口的可组合包装中。

These components are defined either in pure JavaScript or they can be defined in what the React team calls “JSX”. If you decide to use JSX (which you most likely will, it’s pretty standard — and it’s what we’ll use for this tutorial), you’ll need some compile stage to convert your JSX to JavaScript. But we’ll get to this later.

这些组件可以用纯JavaScript定义,也可以用React团队称为“ JSX”的形式定义。 如果您决定使用JSX(这很有可能是很标准的-这就是我们将在本教程中使用的东西),则需要一些编译阶段才能将JSX转换为JavaScript。 但是我们稍后再讨论。

What makes React so convenient for building user interfaces is that data is either received from a component’s parent component, or it’s contained in the component itself. Before we jump into code, let’s make sure we have a high-level understanding of components.

React在构建用户界面方面如此便捷的原因是,数据要么从组件的父组件接收,要么包含在组件本身中。 在进入代码之前,让我们确保对组件有一个高级的了解。

Above we have a picture of my Twitter profile. If we were going to re-create this page in React, we would break different sections up into different components (highlighted). Notice that components can have nested components inside of them. We might name the left component (pink) the UserInfo component. Inside the UserInfo component we have another component (orange), that we could call the UserImages component. The way this parent/child relationship works is our UserInfo component, or the parent component, is where the ‘state’ of the data for both itself and the UserImages component (child component) lives.

上面有我的Twitter个人资料图片。 如果要在React中重新创建此页面,我们会将不同的部分分解为不同的组件(突出显示)。 请注意,组件内部可以具有嵌套组件。 我们可以将左边的组件(粉红色)命名为UserInfo组件。 在UserInfo组件内部,我们还有另一个组件(橙色),可以将其UserImages组件。 父/子关系的工作方式是我们的UserInfo组件或父组件,这是自身和UserImages组件(子组件)的数据“状态”所在的位置。

If we wanted to use any part of the parent component’s data in the child component, which we do, we would pass that data to the child component as an attribute. In this example, we pass the UserImages component all of the images that the user has (which currently live in the UserInfo component). We’ll get more into the details of the code in a bit, but I want you to understand the bigger picture of what’s happening here. This parent/child hierarchy makes managing our data relatively simple because we know exactly where our data lives and we shouldn’t manipulate that data anywhere else.

如果我们想在子组件中使用父组件数据的任何部分(我们这样做),则可以将该数据作为属性传递给子组件。 在此示例中,我们将用户拥有的所有图像(当前位于UserInfo组件中)传递给UserImages组件。 我们稍后将详细介绍代码的细节,但是我希望您了解此处发生的事情的大致情况。 这种父/子层次结构使我们的数据管理相对简单,因为我们确切地知道数据在哪里,我们不应该在其他任何地方操纵该数据。

The topics below are what I believe to be the fundamental aspects of React. If you understand all of them and their purposes, you’ll be at a very good spot after reading this tutorial.

我认为以下主题是React的基本方面。 如果您了解所有这些内容及其用途,那么在阅读了本教程之后,您将处在一个很好的位置。

JSX — Allows us to write HTML like syntax which gets
transformed to lightweightJavaScript objects.

Virtual DOM — A JavaScript representation of the actual
DOM.

React.Component — The way in which you create a new component.

render (method) — Describes what the UI will look like for
the particular component.

ReactDOM.render — Renders a React component to a DOM node.

state — The internal data store (object) of a component.

constructor (this.state) - The way in which you establish
the initial state of a component.

setState — A helper method used for updating the state of a
component and re-rendering the UI

props — The data which is passed to the child component
from the parent component.

propTypes — Allows you to control the presence, or types of
certain props passed to the child component.

defaultProps — Allows you to set default props for your component.

Component LifeCycle
  - componentDidMount — Fired after the component mounted
  - componentWillUnmount — Fired before the component will unmount
  - getDerivedStateFromProps - Fired when the component mounts and
whenever the props change. Used to update the state of a
component when its props change

Events
  - onClick
  - onSubmit
  - onChange

I know it seems like a lot, but you’ll soon see how each piece is fundamental in building robust applications with React (and I also wasn’t kidding when I said I wanted this to be a comprehensive guide).

我知道这看起来很多,但是您很快就会看到,每个部分对于使用React构建健壮的应用程序都是至关重要的(当我说我希望这是一个全面的指南时,我也没有开玩笑)。

At this point you should understand, on a very high level, how React works. Now, let’s jump into some code.

在这一点上,您应该从较高的角度了解React的工作方式。 现在,让我们跳入一些代码。

创建您的第一个组件(JSX,虚拟DOM,渲染,ReactDOM.render) (Creating your First Component (JSX, Virtual DOM, render, ReactDOM.render))

Let's go ahead and build our very first React component.

让我们继续构建第一个React组件。

To create a React component, you'll use an ES6 class.

要创建一个React组件,您将使用ES6类。

import React from 'react'
import ReactDOM from 'react-dom'

class HelloWorld extends React.Component {
  render() {
    return (
      <div>Hello World!</div>
    )
  }
}

ReactDOM.render(<HelloWorld />, document.getElementById('root'));

Notice that the only method on our class is render. Every component is required to have a render method. The reason for that is render is describing the UI (user interface) for our component. So in this example the text that will show on the screen where this component is rendered is Hello World!

注意,类上的唯一方法是render 。 每个组件都必须具有render方法。 渲染的原因是描述组件的UI(用户界面)。 因此,在此示例中,将在呈现此组件的屏幕上显示的文本是Hello World!

Now let's look at what ReactDOM is doing. ReactDOM.render takes in two arguments. The first argument is the component you want to render, the second argument is the DOM node where you want to render the component. (Notice we’re using ReactDOM.render and not React.render. This was a change made in React .14 to make React more modular.

现在让我们看一下ReactDOM在做什么。 ReactDOM.render接受两个参数。 第一个参数是要呈现的组件,第二个参数是要呈现组件的DOM节点。 (注意,我们使用的是ReactDOM.render而不是React.render。这是对React .14所做的更改,以使React更具模块化。

It makes sense when you think that React can render to more things than just a DOM element). In the example above we’re telling React to take our HelloWorld component and render it to the element with an ID of root. Because of the parent/child child relations of React we talked about earlier, you usually only have to use ReactDOM.render once in your application because by rendering the most parent component, all child components will be rendered as well.

当您认为React不仅可以渲染DOM元素之外,还可以渲染更多东西时,这是有道理的。 在上面的示例中,我们告诉React使用我们的HelloWorld组件并将其呈现给ID为root的元素。 由于我们前面已经讨论过React的父/子子关系,您通常只需要在应用程序中使用一次ReactDOM.render,因为通过渲染最父组件,所有子组件也将被渲染。

Now at this point you might feel a little weird throwing “HTML” into your JavaScript. Since you started learning web development, you’ve been told that you should keep your logic out of the view, AKA keep your JavaScript uncoupled from your HTML. This paradigm is strong, but it does have some weaknesses.

现在,您可能会觉得有些奇怪,在您JavaScript中添加了“ HTML”。 自从您开始学习Web开发以来,就被告知应该将逻辑保持在视野之外,AKA可以使JavaScript与HTML脱钩。 这种范例很强大,但确实有一些缺点。

I don’t want to make this tutorial longer trying to convince you that this idea is a step in the right direction, so if this idea still bothers you you can check out this link. As you learn more about React, this uneasiness should quickly subside. The “HTML” that you’re writing in the render method isn’t actually HTML but it’s what React is calling “JSX”. JSX simply allows us to write HTML like syntax which (eventually) gets transformed to lightweight JavaScript objects. React is then able to take these JavaScript objects and from them form a “virtual DOM” or a JavaScript representation of the actual DOM. This creates a win/win situation where you get the accessibility of templates with the power of JavaScript.

我不想让本教程变得更长,试图说服您这个想法是朝正确方向迈出的一步,因此,如果这个想法仍然困扰您,您可以查看此链接 。 当您了解更多有关React的信息时,这种不安情绪很快就会消失。 您在render方法中编写的“ HTML”实际上不是HTML,而是React所说的“ JSX”。 JSX只是允许我们编写类似HTML的语法,而语法最终会转换为轻量级JavaScript对象。 然后,React能够获取这些JavaScript对象,并从它们中形成一个“虚拟DOM”或实际DOMJavaScript表示形式。 这会产生双赢的局面,您可以使用JavaScript的功能来访问模板。

Looking at the example below, this is what your JSX will eventually be compiled into.

看下面的示例,这就是您的JSX最终将被编译成的内容。

class HelloWorld extends React.Component {
  render() {
    return React.createElement("div", null, "Hello World");
  }
}

Now, you can forgo the JSX -> JS transform phase and write your React components like the code above, but as you can imagine, that would be rather tricky. I’m unaware of anyone who is not using JSX. For more information about what JSX compiles down to, check out React Elements vs React Components

现在,您可以放弃JSX-> JS转换阶段,并像上面的代码一样编写您的React组件,但是您可以想象,这非常棘手。 我不知道没有使用JSX的人。 有关JSX编译内容的更多信息,请查看React Elements vs React Components

Up until this point we haven’t really emphasized the importance of this new virtual DOM paradigm we’re jumping into. The reason the React team went with this approach is because, since the virtual DOM is a JavaScript representation of the actual DOM, React can keep track of the difference between the current virtual DOM(computed after some data changes), with the previous virtual DOM (computed befores some data changes).

到目前为止,我们还没有真正强调过要进入的这种新的虚拟DOM范例的重要性。 React团队采用此方法的原因是,由于虚拟DOM是实际DOMJavaScript表示,因此React可以跟踪当前虚拟DOM(在某些数据更改后计算)与先前虚拟DOM之间的差异。 (先计算一些数据)。

React then isolates the changes between the old and new virtual DOM and then only updates the real DOM with the necessary changes. In more layman’s terms, because manipulating the actual DOM is slow, React is able to minimize manipulations to the actual DOM by keeping track of a virtual DOM and only updating the real DOM when necessary and with only the necessary changes. (More info here). Typically UI’s have lots of state which makes managing state difficult. By re-rendering the virtual DOM every time any state change occurs, React makes it easier to think about what state your application is in.

然后,React隔离新旧虚拟DOM之间的更改,然后仅使用必要的更改来更新实际DOM。 用更多的外行术语来说,由于操作实际DOM的速度很慢,因此React可以通过跟踪虚拟DOM并仅在必要时仅对实际DOM进行必要的更改来最小化对实际DOM的操作。 ( 更多信息在这里 )。 通常,UI具有很多状态,这使得管理状态变得困难。 通过在每次状态发生变化时重新渲染虚拟DOM,React使得思考应用程序所处的状态变得更加容易。

The process looks something like this:

该过程如下所示:

Some user event which changes the state of your app → Re-render virtual DOM -> Diff previous virtual DOM with new virtual DOM -> Only update real DOM with necessary changes.

某些用户事件会更改应用程序的状态→重新呈现虚拟DOM->用新的虚拟DOM区分以前的虚拟DOM- >仅通过必要的更改更新真实的DOM。

Because there’s this transformation process from JSX to JS, you need to set up some sort of transformation phase as you’re developing. In part 2 of this series I'll introduce Webpack and Babel for making this transformation.

因为存在从JSX到JS的转换过程,所以在开发时需要设置某种转换阶段。 在本系列的第2部分中,我将介绍Webpack和Babel进行这种转换。

Let’s take a look back at our “Most Important Parts of React” checklist and see where we’re at now.

让我们回顾一下“ React的最重要部分”清单,看看我们现在的位置。

<b>JSX — Allows us to write HTML like syntax which gets transformed
to lightweight JavaScript objects.</b>

<b>Virtual DOM — A JavaScript representation of the actual
DOM.</b>

<b>React.Component — The way in which you create a new component.</b>

<b>render (method) — Describes what the UI will look like for
the particular component.</b>

<b>ReactDOM.render — Renders a React component to a DOM node.</b>

state — The internal data store (object) of a component.

constructor (this.state) - The way in which you establish
the initial state of a component.

setState — A helper method used for updating the state of a
component and re-rendering the UI

props — The data which is passed to the child component
from the parent component.

propTypes — Allows you to control the presence, or types of
certain props passed to the child component.

defaultProps — Allows you to set default props for your component.

Component LifeCycle
  - componentDidMount — Fired after the component mounted
  - componentWillUnmount — Fired before the component will unmount
  - getDerivedStateFromProps - Fired when the component mounts and
whenever the props change. Used to update the state of a
component when its props change

Events
  - onClick
  - onSubmit
  - onChange

We’re making good pace. Everything in bold is what we’ve already covered and you should at least be able to explain how those certain components fit into the React ecosystem.

我们的步伐很好。 粗体字的内容已经涵盖了,您至少应该能够解释这些特定组件如何适应React生态系统。

Adding State to your Component (state)

将状态添加到您的组件(状态)

Next on the list is state. Earlier we talked about how managing user interfaces is difficult because they typically have lots of different states.

列表上的下一个是state 。 前面我们谈到了如何管理用户界面很困难,因为它们通常具有许多不同的状态。

This area is where React really starts to shine. Each component has the ability to manage its own state and pass its state down to child components if needed.

这是React真正开始发光的地方。 每个组件都有能力管理自己的状态,并在需要时将其状态传递给子组件。

Going back to the Twitter example from earlier, the UserInfo component (highlighted in pink above) is responsible for managing the state (or data) of the users information. If another component also needed this state/data but that state wasn’t a direct child of the UserInfo component, then you would create another component that would be the direct parent of the UserInfo and the other component (or both components which required that state), then you would pass the state down as props into the child components. In other words, if you have a multi component hierarchy, a common parent component should manage the state and pass it down to its children components via props.

回到前面的Twitter示例, UserInfo组件(上面的粉红色突出显示)负责管理用户信息的状态(或数据)。 如果另一个组件也需要此状态/数据,但该状态不是UserInfo组件的直接子代,则您将创建另一个组件,该组件将是UserInfo和另一个组件(或两个都需要该状态的组件)的直接父级),然后将状态作为道具传递给子组件。 换句话说,如果您具有多组件层次结构,则公共父组件应管理状态并将其通过prop传递给其子组件。

Let’s take a look at an example component using it’s own internal state.

让我们来看一个使用其自身内部状态的示例组件。

class HelloUser extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      username: 'tylermcginnis'
    }
  }
  render() {
    return (
      <div>
        Hello {this.state.username}
      </div>
    )
  }
}

We’ve introduced some new syntax with this example. The first one you’ll notice is the constructor method. From the definition above, the constructor method is “The way in which you set the state of a component”. In other terms, any data you put on this.state inside of the constructor will be part of that component's state. In the code above we’re telling our component that we want it to keep track of a username. This username can now be used inside our component by doing {this.state.username}, which is exactly what we do in our render method.

在此示例中,我们引入了一些新的语法。 您会注意到的第一个是构造方法。 根据上面的定义,构造方法是“设置组件状态的方式”。 this.state ,您在构造函数中放入this.state任何数据将成为该组件状态的一部分。 在上面的代码中,我们告诉组件我们希望它跟踪username 。 现在,可以通过执行{this.state.username}来在组件内部使用此username ,这正是我们在render方法中所做的。

The last thing to talk about with state is that our component needs the ability to modify its own internal state. We do this with a method called setState.

关于状态的最后一件事是我们的组件需要修改其内部状态的能力。 我们使用名为setState的方法来执行此操作。

Remember earlier when we talked about the re-rendering of the virtual dom whenever the data changes?

还记得我们之前讲过的每当数据更改时虚拟dom的重新渲染吗?

Signal to notify our app some data has changed→ Re-render virtual DOM -> Diffprevious virtual DOM with new virtual DOM -> Only update real DOM with necessarychanges.

发出信号通知我们的应用程序某些数据已更改→重新渲染虚拟DOM-> 用新的虚拟DOM 区分 先前的虚拟DOM->仅在进行必要 更改后 更新实际DOM

That “signal to notify our app some data has changed” is actually just setState. Whenever setState is called, the virtual DOM re-renders, the diff algorithm runs, and the real DOM is updated with the necessary changes.

“通知我们的应用程序某些数据的信号已更改”实际上就是setState。 每当调用setState时,虚拟DOM就会重新渲染,运行diff算法,然后使用必要的更改更新实际DOM。

As a side note, when we introduce setState in the code below, we’re also going to introduce a few events that are on our list. Two birds, one stone.

附带说明一下,在下面的代码中介绍setState时,我们还将介绍列表中的一些事件。 两只鸟,一块石头。

So in the next code sample, we’re going to now have an input box that whenever someone types into it, it will automatically update our state and change the username.

因此,在下一个代码示例中,我们现在将有一个输入框,只要有人在其中输入内容,它就会自动更新我们的状态并更改用户名。

class HelloUser extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      username: 'tylermcginnis'
    }

    this.handleChange = this.handleChange.bind(this)
  }
  handleChange (e) {
    this.setState({
      username: e.target.value
    })
  }
  render() {
    return (
      <div>
        Hello {this.state.username} <br />
        Change Name:
        <input
          type="text"
          value={this.state.username}
          onChange={this.handleChange}
        />
      </div>
    )
  }
}

Note we’ve introduced a few more things. The first thing is the handleChange method. This method is going to get called every time a user types in the input box. When handleChange is called, it’s going to call setState to re-define our username with whatever was typed into the input box (e.target.value). Remember,whenever setState is called, React creates a new virtual DOM, does the diff, then updates the real DOM.

请注意,我们还介绍了其他一些内容。 第一件事是handleChange方法。 每当用户在输入框中键入内容时,就会调用此方法。 调用handleChange ,它将调用setState以使用在输入框中键入的任何内容(例如target.value)重新定义我们的用户名。 请记住,无论何时调用setState ,React都会创建一个新的虚拟DOM,进行比较,然后更新实际DOM。

Now let’s look at our render method. We’ve added a new line that contains an input field. The type of the input field is obviously going to be text. The value is going to be the value of our username which was originally defined in our getInitialState method and will be updated in the handleChange method.

现在让我们看一下我们的render方法。 我们添加了包含输入字段的新行。 输入字段的类型显然将是text 。 该值将是最初在getInitialState方法中定义的用户名的值,并将在handleChange方法中进行更新。

Notice there is a new attribute you’ve probably never seen before, onChange. onChange is a React thing and it will call whatever method you specify every time the value in the input box changes, in this case the method we specified was handleChange.

注意,您可能从未见过的新属性onChangeonChange是一个React事物,每次输入框中的值更改时,它将调用您指定的任何方法,在这种情况下,我们指定的方法是handleChange

The process for the code above would go something like this.

上面代码的过程将如下所示。

A user types into the input box → handleChange is invoked → the state of our component is set to a new value → React re-renders the virtual DOM → React Diffs the change → Real DOM is updated.

用户在输入框中键入→调用handleChange→将组件的状态设置为新值→React重新渲染虚拟DOM→React更改更改→实际DOM更新。

Later on when we cover props, we’ll see some more advanced use cases of handling state.

稍后,当我们介绍道具时,我们将看到一些更高级的处理状态用例。

We’re getting there! If you can’t explain the items in bold below, go re-read that section. One tip on REALLY learning React, don’t let passively reading this give you a false sense of security that you actually know what’s going on and can re-create what we’re doing.

我们到了! 如果您无法在下面用粗体解释这些项目,请重新阅读该部分。 关于真正学习React的一个技巧,不要让被动阅读它给您一种错误的安全感,使您真正了解正在发生的事情并可以重新创建我们正在做的事情。

Head over to CodeSandbox and try to recreate (or create your own) components without looking at what I’ve done. It’s the onlyway you’ll truly start learning how to build with React. This goes for this tutorial and the following to come.

转至CodeSandbox,尝试重新创建(或创建自己的)组件,而不用看我所做的事情。 这是您真正开始学习如何使用React进行构建的唯一途径。 这适用于本教程和后续内容。

<b>JSX — Allows us to write HTML like syntax which gets transformed
to lightweight JavaScript objects.</b>

<b>Virtual DOM — A JavaScript representation of the actual
DOM.</b>

<b>React.Component — The way in which you create a new component.</b>

<b>render (method) — Describes what the UI will look like for
the particular component.</b>

<b>ReactDOM.render — Renders a React component to a DOM node.</b>

<b>state — The internal data store (object) of a component.</b>

<b>constructor (this.state) - The way in which you establish
the initial state of a component.</b>

<b>setState — A helper method used for updating the state of a
component and re-rendering the UI</b>

props — The data which is passed to the child component
from the parent component.

propTypes — Allows you to control the presence, or types of
certain props passed to the child component.

defaultProps — Allows you to set default props for your component.

Component LifeCycle
  - componentDidMount — Fired after the component mounted
  - componentWillUnmount — Fired before the component will unmount
  - getDerivedStateFromProps - Fired when the component mounts and
whenever the props change. Used to update the state of a
component when its props change

Events
  - onClick
  - onSubmit
  - onChange

Receiving State from Parent Component (props, propTypes, getDefaultProps)

从父组件接收状态(props,propTypes,getDefaultProps)

We’ve talked about props a few times already since it’s hard to really do much without them. By our definition above, props is the data which is passed to the child component from the parent component. This allows for our React architecture to stay pretty straight forward. Handle state in the highest most parent component which needs to use the specific data, and if you have a child component that also needs that data, pass that data down as props.

我们已经多次谈论道具,因为没有道具很难真正做很多事情。 根据上面的定义,props是从父组件传递到子组件的数据。 这使我们的React架构保持非常直接。 在需要使用特定数据的最高父组件中处理状态,如果您的子组件也需要该数据,则将该数据作为道具传递。

Here’s a very basic example of using props.

这是使用道具的一个非常基本的例子。

class HelloUser extends React.Component {
  render() {
    return (
      <div> Hello, {this.props.name}</div>
    )
  }
}

ReactDOM.render(<HelloUser name="Tyler"/>, document.getElementById('root'));

Notice on line 9 we have an attribute called name with a value of “Tyler”. Now in our component, we can use {this.props.name} to get “Tyler”.

注意,在第9行,我们有一个名为name的属性,其值为“ Tyler”。 现在在组件中,我们可以使用{this.props.name}来获取“ Tyler”。

Let’s look at a more advanced example. We’re going to have two components now. One parent, one child. The parent is going to keep track of the state and pass a part of that state down to the child as props. Let’s first take a look at that parent component.

让我们看一个更高级的例子。 现在,我们将有两个部分。 一位父母,一位孩子。 父母将跟踪该状态并将该状态的一部分作为道具传递给孩子。 首先让我们看一下该父组件。

Parent Component:

父组件:

class FriendsContainer extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      name: 'Tyler McGinnis',
      friends: ['Jake Lingwall', 'Sarah Drasner', 'Merrick Christensen']
    }
  }
  render() {
    return (
      <div>
        <h3> Name: {this.state.name} </h3>
        <ShowList names={this.state.friends} />
      </div>
    )
  }
}

There really isn’t much going on in this component that we haven’t seen before. We have an initial state and we pass part of that initial state to another component. The majority of the new code will come from this child component so let’s take a closer look at that.

实际上,我们之前从未见过的该组件中并没有发生太多事情。 我们有一个初始状态,并将该初始状态的一部分传递给另一个组件。 新代码的大部分将来自此子组件,因此让我们对其进行仔细研究。

Child Component:

子组件:

class ShowList extends React.Component {
  render() {
    return (
      <div>
        <h3> Friends </h3>
        <ul>
          {this.props.names.map((friend) => <li>{friend}</li>)}
        </ul>
      </div>
    )
  }
}

Remember that the code that gets returned from our render method is a representation of what the real DOM should look like. If you’re not familiar with Array.prototype.map, this code might look a little wonky. All map does is it creates a new array, calls our callback function on each item in the array, and fills the new array with the result of calling the callback function on each item. For example,

请记住,从我们的render方法返回的代码代表了真实DOM的外观。 如果您不熟悉Array.prototype.map ,则此代码可能看起来有些奇怪。 map所做的只是创建一个新数组,在数组中的每个项目上调用我们的回调函数,并使用在每个项目上调用回调函数的结果填充新数组。 例如,

const friends = ['Jake Lingwall', 'Sarah Drasner', 'Merrick Christensen'];
const listItems = friends.map((friend) => {
  return "<li> " + friend + "</li>";
});

console.log(listItems);
// ["<li> Jake Lingwall</li>", "<li> Sarah Drasner</li>", "<li> Merrick Christensen</li>"];

The console.log above returns ["<li> Jake Lingwall</li>", "<li> Murphy Randall</li>", "<li> Merrick Christensen</li>"].

上面的console.log返回["<li> Jake Lingwall</li>", "<li> Murphy Randall</li>", "<li> Merrick Christensen</li>"]

Notice all that happened was we made a new array and added <li> </li> to each item in the original array.

注意所有发生的事情是我们创建了一个新数组并将<li> </li>到原始数组中的每个项目。

What’s great about map is it fits perfectly into React (and it’s built into JavaScript). So in our child component above, we’re mapping over names, wrapping each name in a pair of <li> tags, and saving that to our listItems variable. Then, our render method returns an unordered list with all of our friends.

map的最大优点是它完全适合React(并且内置在JavaScript中)。 因此,在上面的子组件中,我们正在映射名称,将每个名称包装在一对<li>标记中,然后将其保存到我们的listItems变量中。 然后,我们的render方法返回与我们所有朋友的无序列表。

Let’s look at one more example before we stop talking about props. It’s important to understand that wherever the data lives, is the exact place you want to manipulate that data. This keeps it simple to reason about your data.

在停止谈论道具之前,让我们再看一个例子。 重要的是要了解,无论数据位于何处,都是要操纵该数据的确切位置。 这样可以使推理数据变得简单。

All getter/setter method for a certain piece of data will always be in the same component where that data was defined. If you needed to manipulate some piece of data outside where the data lives, you’d pass the getter/setter method into that component as props. Let’s take a look at an example like that.

特定数据的所有getter / setter方法将始终位于定义该数据的同一组件中。 如果您需要在数据所在的地方之外处理某些数据,则可以将getter / setter方法作为道具传递给该组件。 让我们看一个类似的例子。

class FriendsContainer extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      name: 'Tyler McGinnis',
      friends: [
        'Jake Lingwall',
        'Sarah Drasner',
        'Merrick Christensen'
      ],
    }

    this.addFriend = this.addFriend.bind(this)
  }
  addFriend(friend) {
    this.setState((state) => ({
      friends: state.friends.concat([friend])
    }))
  }
  render() {
    return (
      <div>
        <h3> Name: {this.state.name} </h3>
        <AddFriend addNew={this.addFriend} />
        <ShowList names={this.state.friends} />
      </div>
    )
  }
}

Notice that in our addFriend method we introduced a new way to invoke setState. Instead of passing it an object, we're passing it a function which is then passed state. Whenever you're setting the new state of your component based on the previous state (as we're doing with our friends array), you want to pass setState a function which takes in the current state and returns the data to merge with the new state.

注意,在我们的addFriend方法中,我们引入了一种调用setState的新方法。 与其传递一个对象,不如传递一个函数,然后传递给state 。 每当您基于以前的状态设置组件的新状态时(就像我们对friends数组所做的那样),您都想向setState传递一个函数,该函数接受当前状态并返回数据以与新状态合并州。

class AddFriend extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      newFriend: ''
    }

    this.updateNewFriend = this.updateNewFriend.bind(this)
    this.handleAddNew = this.handleAddNew.bind(this)
  }
  updateNewFriend(e) {
    this.setState({
      newFriend: e.target.value
    })
  }
  handleAddNew() {
    this.props.addNew(this.state.newFriend)
    this.setState({
      newFriend: ''
    })
  }
  render() {
    return (
      <div>
        <input
          type="text"
          value={this.state.newFriend}
          onChange={this.updateNewFriend}
        />
        <button onClick={this.handleAddNew}> Add Friend </button>
      </div>
    )
  }
}
class ShowList extends React.Component {
  render() {
    return (
      <div>
        <h3> Friends </h3>
        <ul>
          {this.props.names.map((friend) => {
            return <li> {friend} </li>
          })}
        </ul>
      </div>
    )
  }
}

You’ll notice the code above is mostly the same as the previous example, except now we have the ability to add a name to our friends list. Notice how I created a new AddFriend component that manages the new friend we’re going to add. The reason for this is because the parent component (FriendContainer) doesn’t care about the new friend you’re adding, it only cares about all of your friends as a whole (the friends array). However, because we’re sticking with the rule of only manipulate your data from the component that cares about it, we’ve passed the addFriend method down into our AddFriend component as a prop and we call it with the new friend once the handleAddNew method is called.

您会注意到上面的代码与前面的示例基本相同,只是现在我们可以将名称添加到朋友列表中了。 注意,我如何创建一个新的AddFriend组件来管理我们要添加的新朋友。 这样做的原因是因为父组件(FriendContainer)不在乎您要添加的新朋友,而仅在乎您整体上的所有朋友(friends数组)。 但是,由于我们坚持只处理您关心的组件中的数据的规则,因此我们将addFriend方法作为道具传递给了AddFriend组件,一旦handleAddNew方法被我们称为新朋友叫做。

At this point I recommend you try to recreate this same functionality on your own using the code above as a guidance once you’ve been stuck for 3-4 minutes.

在这一点上,我建议您在停留3-4分钟后,尝试使用上面的代码作为指导来重新创建相同的功能。

Before we move on from props, I want to cover two more React features regarding props. They are propTypes and defaultProps. I won’t go into too much detail here because both are pretty straight forward.

在继续介绍道具之前,我想介绍另外两个关于道具的React功能。 它们是propTypesdefaultProps。 我在这里不做过多介绍,因为两者都很简单。

prop-types allow you to control the presence, or types of certain props passed to the child component. With propTypes you can specify that certain props are required or that certain props be a specific type.

prop-types允许您控制传递给子组件的某些prop的存在或类型。 使用propTypes可以指定某些道具是必需的,或者某些道具是特定的类型。

As of React 15, PropTypes is no longer included with the React package. You'll need to install it separately by running npm install prop-types.

从React 15开始,PropTypes不再包含在React包中。 您需要通过运行npm install prop-types单独安装它。

defaultProps allow you to specify a default (or a backup) value for certain props just in case those props are never passed into the component.

defaultProps允许您为某些道具指定默认(或备用)值,以防万一这些道具永远不会传递到组件中。

I’ve modified our components from earlier to now, using propTypes, require that addFriend is a function and that it’s passed into the AddFriend component. I’ve also, using defaultProps, specified that if no array of friends is given to the ShowList component, it will default to an empty array.

我已经使用propTypes修改了我们的组件,要求addFriend是一个函数,并将其传递到AddFriend组件中。 我还使用defaultProps指定,如果没有给ShowList组件提供朋友数组,它将默认为一个空数组。

import React from 'react'
import PropTypes from 'prop-types'

class AddFriend extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      newFriend: ''
    }
  }
  updateNewFriend(e) {
    this.setState({
      newFriend: e.target.value
    })
  }
  handleAddNew() {
    this.props.addNew(this.state.newFriend)
    this.setState({
      newFriend: ''
    })
  }
  render() {
    return (
      <div>
        <input type="text" value={this.state.newFriend} onChange={this.updateNewFriend} />
        <button onClick={this.handleAddNew}> Add Friend </button>
      </div>
    )
  }
}

AddFriend.propTypes: {
  addNew: PropTypes.func.isRequired
}
class ShowList extends React.Component {
  render() {
    return (
      <div>
        <h3> Friends </h3>
        <ul>
          {this.props.names.map((friend) => {
            return <li> {friend} </li>
          })}
        </ul>
      </div>
    )
  }
}

ShowList.defaultProps = {
  names: []
}

Alright, we’re on the last stretch for this first tutorial. Let’s take a look atour guide and see what we have left.

好了,我们在第一个教程的最后一步。 让我们看看我们的指南,看看剩下的内容。

<b>JSX — Allows us to write HTML like syntax which gets transformed
to lightweight JavaScript objects.</b>

<b>Virtual DOM — A JavaScript representation of the actual
DOM.</b>

<b>React.Component — The way in which you create a new component.</b>

<b>render (method) — Describes what the UI will look like for
the particular component.</b>

<b>ReactDOM.render — Renders a React component to a DOM node.</b>

<b>state — The internal data store (object) of a component.</b>

<b>constructor (this.state) - The way in which you establish
the initial state of a component.</b>

<b>setState — A helper method used for updating the state of a
component and re-rendering the UI</b>

<b>props — The data which is passed to the child component
from the parent component.</b>

<b>prop-types — Allows you to control the presence, or types of
certain props passed to the child component.</b>

<b>defaultProps — Allows you to set default props for your component.</b>

Component LifeCycle
  - componentDidMount — Fired after the component mounted
  - componentWillUnmount — Fired before the component will unmount
  - getDerivedStateFromProps - Fired when the component mounts and
whenever the props change. Used to update the state of a
component when its props change

<b>Events
  - onClick
  - onSubmit
  - onChange
</b>

We’re so close!

我们是如此接近!

Component LifeCycle

组件生命周期

Each component you make will have its own lifecycle events that are useful for various things. For example, if we wanted to make an ajax request on the initial render and fetch some data, where would we do that? Or, if we wanted to run some logic whenever our props changed, how would we do that? The different lifecycleevents are the answers to both of those. Let’s break them down.

您制作的每个组件都会有自己的生命周期事件,这些事件对于各种事情都非常有用。 例如,如果我们想在初始渲染中发出ajax请求并获取一些数据,我们该在哪里做? 或者,如果我们想在道具更改时运行一些逻辑,我们该怎么做? 不同的生命周期事件是这两种情况的答案。 让我们分解一下。

class App extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      name: 'Tyler McGinnis'
    }
  }
  componentDidMount(){
    // Invoked once the component is mounted to the DOM
    // Good for making AJAX requests
  }
  static getDerivedStateFromProps(nextProps, prevState) {
    // The object you return from this function will
    // be merged with the current state.
  }
  componentWillUnmount(){
    // Called IMMEDIATELY before a component is unmounted
    // Good for cleaning up listeners
  }
  render() {
    return (
      <div>
        Hello, {this.state.name}
      </div>
    )
  }
}

componentDidMount - Invoked once after the initial render. Because the component has already been invoked when this method is invoked, you have access to the virtual DOM if you need it. You do that by calling this.getDOMNode(). So this is the lifecycleevent where you’ll be making your AJAX requests to fetch some data.*

componentDidMount-初始渲染后调用一次。 因为在调用此方法时已经调用了组件,所以如果需要,您可以访问虚拟DOM。 您可以通过调用this.getDOMNode() 。 因此,这是生命周期事件,您将在其中发出AJAX请求以获取一些数据。*

componentWillUnmount - This life cycle method is invoked immediately before a component is unmounted from the DOM. This is where you can do necessary clean up.

componentWillUnmount-从DOM上卸载组件之前,将立即调用此生命周期方法。 在这里您可以进行必要的清理。

getDerivedStateFromProps - Sometimes you'll need to update the state of your component based on the props that are being passed in. This is the lifecycle method in which you'd do that. It'll be passed the props and the state, and the object you return will be merged with the current state.

getDerivedStateFromProps-有时您需要根据传入的道具更新组件的状态。这是您在其中执行的生命周期方法。 它将传递道具和状态,并且您返回的对象将与当前状态合并。

Well, if you stuck with me until this point, great job. I hope this tutorial was beneficial to you and you now feel at least mildly comfortable with React.

好吧,如果您一直坚持到现在,那就太好了。 我希望本教程对您有所帮助,并且您现在至少对React感到有点满意。

For a much more in depth look at the fundamentals of React, check out my React Fundamentals course.

要更深入地了解React的基础知识 ,请查看我的React基础知识课程。

翻译自: https://www.freecodecamp.org/news/a-comprehensive-guide-to-react-js-in-2018-ba8bb6975597/

2018 react 大会

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值