React 教程:2018年学习 React.js 的综合指南

10年服务1亿前端开发工程师

小编推荐:掘金是一个面向程序员的高质量技术社区,从 一线大厂经验分享到前端开发最佳实践,无论是入门还是进阶,来掘金你不会错过前端开发的任何一个技术干货。

组件(Component) 是 React的构建块。如果你有 Angular 技术背景,那么组件(Component) 与 Directives 非常相似。如果你来自其他的技术背景,那么它们本质上是小部件或模块。您可以将组件视为 HTML,CSS,JS 的集合以及特定于该组件的一些内部数据。我喜欢将 React 组件视为 Web 中的水果派 。它们拥有您需要的一切,将美味随心所欲的组合并包裹起来。这些组件定义在纯 JavaScript 中,或者可以在 React 团队称为“JSX”的内容中定义。如果您决定使用JSX(您很可能会使用它,它非常标准 – 我们将在本教程中使用),你需要一些编译阶段来将你的 JSX 转换为 JavaScript ,我们稍后会讨论这个问题。

React 构建用户界面如此方便的原因在于,数据(data) 要么来自组件的父组件,要么包含在组件自身之中。在我们开始编写代码之前,让我们先确保对组件有高度的理解。

上面的图片是我个人的 Twitter 资料图片。如果我们要用 React 重构这个页面,我们会将页面中的不同的部分分成不同的组件(已经用有颜色的框突显)。请注意,组件内部可以嵌套组件。我们可能将左侧组件(粉红色)命名为 UserInfo 组件。在 UserInfo 组件内部,我们有另一个组件(橙色),我们可以命名为 UserImages 组件。这种 父/子 关系的工作方式是 UserInfo 组件或父组件,和 UserImages 组件(子组件)的数据存在于 “state(状态)” 中。如果我们想在子组件中使用父组件数据的任何部分(我们这样做),我们会将该数据作为props属性传递给子组件。在此示例中,我们将用户拥有的所有图像(当前存在于UserInfo组件中)传递给 UserImages 组件。我们将更多地了解代码的细节,但我希望您能够大概了解这里发生的事情。这种 父/子 层次结构使得管理我们的数据变得相对简单,因为我们确切知道数据存在的位置,我们不应该在其他地方操纵这些数据。

了解一下 stateprops之间最重要的区别

以下主题是我认为是 React 最重要的部分。 如果您了解所有这些内容及其目的,那么你可以很容易阅读和理解本教程。

  1. JSX – 允许我们编写类似HTML的语法 转换为lightweightJavaScript对象。
  2. 虚拟DOM – 实际DOM的JavaScript表示。
  3. React.Component – 您创建新组件的方式
  4. render(方法) – 描述特定组件的 UI 外观 。
  5. ReactDOM.render – 将React组件渲染到DOM节点。
  6. state – 组件的内部数据存储(对象)。
  7. constructor(this.state) – 建立组件初始 state(状态) 的方式。
  8. setState – 一种辅助方法,用于更新组件的 state(状态) 并重新渲染 UI。
  9. props – 从父组件传递给子组件的数据。
  10. propTypes – 允许您控制传递给子组件的某些 props(属性) 的存在或类型。
  11. defaultProps – 允许您为组件设置默认 props(属性) 。
  12. 组件的生命周期
    • componentDidMount – 装载组件后触发
    • componentWillUnmount – 在组件卸载之前触发
    • getDerivedStateFromProps – 当组件装载时以及每当 props 更改时触发。 用于在其 props(属性) 更改时更新组件的状态
  13. 事件
    • onClick
    • onSubmit
    • onChange

我知道它看起来很多,但你很快就会看到每一个都是 React 用于构建强大的应用程序的基础(当我说我希望这是一个全面的指南时我也不是在开玩笑)。

在这一点上,您应该在很高的层次上理解 React 的工作原理。 现在,让我们进入代码实际应用。

创建第一个组件(JSX,Virtual DOM,render,ReactDOM.render)

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

要创建React组件,您将使用 ES6 class(类)。

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'));

请注意,我们 class 中唯一的方法是 render 。每个组件都需要一个 render 方法。原因是 render 是用来描述我们组件的UI(用户界面)。因此,在此示例中,此组件将在屏幕上渲染的文本是 Hello World!现在让我们看看 ReactDOM 正在做什么。ReactDOM.render 接受两个参数。第一个参数是要渲染的组件。第二个参数是要渲染组件的 DOM 节点。(请注意,我们使用的是 ReactDOM.render 而不是 React.render 。这是在 React 14 中做出的改变,使得 React 更加模块化。当您认为 React 可以渲染的不仅仅是 DOM 元素时,这是有道理的。)在上面的例子中,我们告诉 React 使用我们的 HelloWorld 组件并将其渲染到 ID 为 root 的 DOM 元素。由于我们之前谈过的 React 的父/子组件关系,你通常只需要在你的应用程序中使用一次 ReactDOM.render,因为通过渲染最顶层的父组件,所有子组件也将被渲染。

现在,你可能会觉得有点奇怪的是在你的 JavaScript 中投入“HTML”。自从你开始学习 web 开发以来,你就一直被告知你应该把你的逻辑放在 视图 之外,也就是说将您的JavaScript 与 HTML 分开。这种观念很强,但确实存在一些缺点。我不想让本教程更长时间,试图说服你,这个想法是朝着正确的方向迈出的一步,所以,如果这个想法仍然困扰你,你可以看看这个链接。随着您对 React 的了解越来越多,这种不安应该会很快消除。您在 render 方法中编写的“HTML”实际上并不是HTML,在 React 中称之为 “JSX”。JSX 只允许我们编写 HTML 语法,这些语法最终会转换为轻量级 JavaScript 对象。然后,React 能够获取这些 JavaScript 对象,并从中形成 “虚拟DOM” 或 实际 DOM 的 JavaScript 表示形式。这创造了一个双赢局面,您可以通过 JavaScript 获得模板的可访问性。

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

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

现在,您可以放弃 JSX -> JS 转换阶段并编写您的React组件,如上面的代码,但你可以想象,这将是相当棘手的。我没有碰到过到不使用 JSX 的人。 有关JSX编译的更多信息,查看 React Elements vs React Components

到目前为止,我们还没有真正强调这个新的虚拟DOM范例的重要性。React 团队采用这种方法的原因是因为虚拟 DOM 是实际 DOM 的 JavaScript 表示,React 可以跟踪当前虚拟 DOM (在一些数据更改后计算)和 先前的虚拟DOM(在某些数据更改之前计算)之间的差异。然后,React 隔离旧虚拟 DOM 和新虚拟 DOM 之间的更改,然后仅使用必要的更改更新真实的 DOM 。在更多给门外汉的术语中我们经常这么,因为操纵实际的 DOM 很慢,React 能够通过跟踪虚拟DOM并仅在必要时仅使用必要的更改来更新真实DOM,最小化对实际DOM的操作。通常,UI具有许多 state(状态) ,这使得管理状态变得困难。通过每次 state(状态) 更改时重新渲染虚拟DOM,React 可以更轻松地识别您的应用程序所处的 state(状态) 。他的过程看起来像这样,

一些用户事件改变应用程序的 state(状态) → 重新渲染虚拟 DOM → 比较新虚拟DOM和以前的虚拟DOM的区别 → 仅更新有必要更改的真实 DOM 。

因为存在从 JSX 到 JS 的转换过程,所以在开发过程中需要设置某种转换阶段。 在后面的中,我将介绍 Webpack 和 Babel 进行这种转换。请参阅:React 教程:如何使用 webpack 4 和 Babel 构建 React 应用(2018)

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

  1. JSX – 允许我们编写类似HTML的语法 转换为lightweightJavaScript对象。✓
  2. 虚拟DOM – 实际DOM的JavaScript表示。✓
  3. React.Component – 您创建新组件的方式。✓
  4. render(方法) – 描述特定组件的 UI 外观 。✓
  5. ReactDOM.render – 将React组件渲染到DOM节点。✓
  6. state – 组件的内部数据存储(对象)。
  7. constructor(this.state) – 建立组件初始 state(状态) 的方式。
  8. setState – 一种辅助方法,用于更新组件的 state(状态) 并重新渲染 UI。
  9. props – 从父组件传递给子组件的数据。
  10. propTypes – 允许您控制传递给子组件的某些 props(属性) 的存在或类型。
  11. defaultProps – 允许您为组件设置默认 props(属性) 。
  12. 组件的生命周期
    • componentDidMount – 装载组件后触发
    • componentWillUnmount – 在组件卸载之前触发
    • getDerivedStateFromProps – 当组件装载时以及每当 props 更改时触发。 用于在其 props(属性) 更改时更新组件的状态
  13. 事件
    • onClick
    • onSubmit
    • onChange

我们的节奏很快。重要的内容都是我们已经涵盖的内容,您至少应该能够解释这些特定组件是如何融入 React 生态系统的。

将 state(状态) 添加到组件

清单列表中的下一个是 state(状态) 。之前我们讨论过如何管理用户界面很困难,因为它们通常有很多不同的状态。这块内容是 React 真正闪耀的地方。每个组件都能够管理自己的 state(状态) ,并在需要时将其 state(状态) 传递给子组件。回到之前的 Twitter 示例页面,UserInfo 组件(以粉红色突出显示)负责管理用户信息的 state(状态)(或数据)。如果另一个组件也需要此 state(状态)/data(数据),但该 state(状态) 不是 UserInfo 组件的直接子项,那么你将创建另一个组件,它将是 UserInfo和另一个组件(或者需要该状态的两个组件)的直接父组件,然后你将 state(状态) 作为 props(属性) 传递给子组件。换句话说,如果您具有多层次结构的组件,则公共父组件应该管理 state(状态) 并通过 props(属性) 将其传递给其子组件。

让我们看一下使用它自己的内部 state(状态) 的示例组件。

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

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

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

最后要讨论的是,我们的组件需要能够修改自己的内部 state(状态) 。我们使用名为 setState 的方法执行此操作。还记得早些时候我们谈到数据发生变化时重新渲染虚拟 DOM 吗?

信号通知我们的应用程序某些数据已更改 → 重新渲染虚拟 DOM → 比较新虚拟DOM和以前的虚拟DOM的区别 → 仅更新有必要更改的真实 DOM 。

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

作为旁注,当我们在下面的代码中引入 setState 时,我们还将介绍我们列表中的一些事件。 一石两鸟。

因此,在下一个代码示例中,我们现在将有一个输入框,只要有人输入它,它就会自动更新我们的状态并更改 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>
    )
  }
}

愚人码头注:

这里有 onChange 事件特别需要注意的是,你需要在 constructor 中绑定this,即:this.handleChange = this.handleChange.bind(this)。不管是新手还是老手,都容易忽视。详情参见:React 官方文档-处理事件 。我们可以用箭头函数加以改造:

import React from "react";
import ReactDom from "react-dom";

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

    this.state = {
      username: "愚人码头"
    };

    //this.handleChange = this.handleChange.bind(this)
  }

  handleChange(e) {
    this.setState({
      username: e.target.value
    });
  }

  render() {
    return (
      <div>
        Hello {this.state.username} !<br />
        修改用户名:
        <input
          type="text"
          value={this.state.username}
          onChange={e => this.handleChange(e)}
        />
      </div>
    );
  }
}

const root = document.getElementById("root");
ReactDom.render(<HelloUser />, root);

请注意,我们已经介绍了一些其他内容。 第一件事是 handleChange 方法。每次用户在输入框中键入时,都会调用此方法。当调用 handleChange 时,它将调用 setState 都会使用输入框中输入的内容( e.target.value )重新定义我们的 username 。请记住,每当调用 setState 时,React都会创建一个新的虚拟DOM,执行 diff ,然后更新真正的DOM。

现在让我们看看我们的 render 渲染方法。我们添加了一个输入框。输入框的 typetext 。其 value 值将是我们 username 的值,该 username 最初在我们的 getInitialState 方法中定义,并将在 handleChange 方法中更新。
请注意,有一个你可能从未见过的新属性,onChangeonChange 是一个 React 内部事件,并且每次输入框中的值发生变化时,它都会调用您指定的任何方法,在上面的示例中,我们指定的方法是 handleChange

愚人码头注:onChange 是一个 React 内部事件,不同于我们熟知的 HTML 的 onChange 属性。React 实现了一个独立于浏览器的 DOM 系统,用于提高性能和跨浏览器兼容性。 详情参见:React 官方文档-DOM 元素(Elements)

上面代码的过程就是这样的。

一个用户输入框键入用户名 → 调用 handleChange → 我们的组件 state(状态) 设置为新值 → React重新渲染虚拟DOM → React 比较变化 → 真实 DOM 更新。

稍后我们会介绍 props(属性) ,我们会看到一些处理 state(状态) 的更高级用例。

到目前位置,如果您无法解释下面打勾粗体项,请重新阅读上面的该部分内容。一个真正学习 React 的提示,不要让被动阅读给你一种虚假的安全感,你实际上知道发生了什么,可以跟着我们一步一步敲代码实现。进入 CodeSandbox 网站,并尝试重新创建(或创建自己的)组件,而不是看我做了什么。这是你真正开始学习如何用 React 构建的唯一方法。这适用于本教程以及随后的内容。

  1. JSX – 允许我们编写类似HTML的语法 转换为lightweightJavaScript对象。✓
  2. 虚拟DOM – 实际DOM的JavaScript表示。✓
  3. React.Component – 您创建新组件的方式。✓
  4. render(方法) – 描述特定组件的 UI 外观 。✓
  5. ReactDOM.render – 将React组件渲染到DOM节点。✓
  6. state – 组件的内部数据存储(对象)。✓
  7. constructor(this.state) – 建立组件初始 state(状态) 的方式。✓
  8. setState – 一种辅助方法,用于更新组件的 state(状态) 并重新渲染 UI。✓
  9. props – 从父组件传递给子组件的数据。
  10. propTypes – 允许您控制传递给子组件的某些 props(属性) 的存在或类型。
  11. defaultProps – 允许您为组件设置默认 props(属性) 。
  12. 组件的生命周期
    • componentDidMount – 装载组件后触发
    • componentWillUnmount – 在组件卸载之前触发
    • getDerivedStateFromProps – 当组件装载时以及每当 props 更改时触发。 用于在其 props(属性) 更改时更新组件的状态
  13. 事件
    • onClick
    • onSubmit
    • onChange

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

我们已经讨论了几次 props(属性) ,因为没有它们很难真正做很多事情。根据我们上面的定义,props(属性) 是从父组件传递给子组件的数据。这使我们的 React 架构保持非常直接。处理需要使用特定数据的最高层级的父组件中的 state(状态) ,如果您有一个需要该数据的子组件,将这些数据作为 props(属性) 传递下去。

这是使用 props(属性) 的一个非常基本的例子。

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

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

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

让我们看一个更高级的例子。 我们现在要有两个组件。 一个父组件,一个子组件。 父组件将跟踪 state(状态) 并将该 state(状态) 的一部分作为 props(属性) 传递给组件。 我们先来看看那个父组件。

父组件:

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>
    )
  }
}

我们之前从未见过的这个组件确实没有太大的进展。 我们有一个初始 state(状态) ,我们将该初始 state(状态) 的一部分传递给另一个组件。 大多数新代码都来自这个子组件,所以让我们仔细看看。

子组件:

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

请记住,从 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);
console.log(friends);
// ["<li> Jake Lingwall</li>", "<li> Sarah Drasner</li>", "<li> Merrick Christensen</li>"];

上面的 console.log 的打印结果是:[“<li> Jake Lingwall</li>”, “<li> Murphy Randall</li>”, “<li> Merrick Christensen</li>”] 。

请注意,所有发生的事情是我们创建了一个新数组,并将 &lt;li&gt;&lt;/li&gt; 添加到原始数组中的每个项。

map 方法非常适合 React(它是 JavaScript 中内置方法)。因此,在上面的子组件中,我们将映射好友的名字,将每个名字包装在 &lt;li&gt; 标记中,并将其保存到 listItems 变量中。然后,我们的 render 方法返回一个包含所有朋友的无序列表。

在我们停止讨论 props(属性) 之前,让我们再看一个例子。重要的是要了解数据所在的位置,是您想要操纵该数据的确切位置。这样可以简单地推断您的数据。用于某个数据的所有 getter / setter 方法将始终位于定义该数据的同一组件中。如果您需要在数据所在的位置之外操作某些数据,则将 getter / setter 方法作为props传递到该组件中。我们来看看这样的例子吧。

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>
    )
  }
}

请注意,在我们的 addFriend 方法中,我们引入了一种调用 setState 的新方法。我们传递一个函数,然后在该函数中传递 state(状态) ,而不是传递一个对象。每当你根据以前的 state(状态) 设置组件的新 state(状态) 时(就像我们对我们的 friends 数组一样),你想传递一个函数,该函数接受当前 state(状态) 并返回数据以与新 state(状态) 合并。

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>
    )
  }
}

您会注意到上面的代码与前面的示例大致相同,但现在我们可以为朋友列表添加一个朋友名字。请注意我是如何创建一个新的 AddFriend 组件来管理我们要添加的新朋友。这是因为父组件( FriendContainer )并不关心你要添加的新朋友,它只关心你所有的朋友(friends数组)。但是,因为我们坚持一个规则,就是只处理该组件所关注的数据,我们已经将 addFriend 方法作为 props(属性) 传递给我们的 AddFriend 组件,并且一旦调用了 handleAddNew 方法,我们就会传递新朋友名字调用它。

一旦你感到困惑,我建议您花3-4分钟,尝试使用上面的代码自己重新创建相同的功能作为实践。

在我们继续 props(属性) 之前,我想再介绍两个关于 props(属性) 的 React 特性。它们是 propTypesdefaultProps。我不会在这里详细介绍,因为两者都很直接。

prop-types允许您控制传递给子组件的某些 props(属性) 的存在或类型。使用propTypes,您可以指定需要某些 props(属性) 或某些 props(属性) 是特定类型。

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

defaultProps 允许您为某些 props(属性) 指定默认(或备份)值,以防这些 props(属性) 永远不会传递到组件中。

我已经使用 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: []
}

好的,我们正处于该教程的最后一段。让我们来看看我们的指南,看看我们还剩下什么。

  1. JSX – 允许我们编写类似HTML的语法 转换为lightweightJavaScript对象。✓
  2. 虚拟DOM – 实际DOM的JavaScript表示。✓
  3. React.Component – 您创建新组件的方式。✓
  4. render(方法) – 描述特定组件的 UI 外观 。✓
  5. ReactDOM.render – 将React组件渲染到DOM节点。✓
  6. state – 组件的内部数据存储(对象)。✓
  7. constructor(this.state) – 建立组件初始 state(状态) 的方式。✓
  8. setState – 一种辅助方法,用于更新组件的 state(状态) 并重新渲染 UI。✓
  9. props – 从父组件传递给子组件的数据。✓
  10. propTypes – 允许您控制传递给子组件的某些 props(属性) 的存在或类型。✓
  11. defaultProps – 允许您为组件设置默认 props(属性) 。 ✓
  12. 组件的生命周期
    • componentDidMount – 装载组件后触发
    • componentWillUnmount – 在组件卸载之前触发
    • getDerivedStateFromProps – 当组件装载时以及每当 props 更改时触发。 用于在其 props(属性) 更改时更新组件的状态
  13. 事件✓
    • onClick✓
    • onSubmit✓
    • onChange✓

就快完成了!

组件的生命周期

您创建的每个组件都有自己的生命周期事件,可用于多个方面的事情。例如,如果我们想在初始渲染上发出 ajax 请求并获取一些数据,我们会在哪里这样做?或者,如果我们想在 props(属性) 改变时运行一些逻辑,我们怎么做?不同的生命周期事件是这两个问题的答案。让我们分解吧。

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

    this.state = {
      name: 'Tyler McGinnis'
    }
  }
  componentDidMount(){
    // 将组件装载到DOM后调用
    // 适合 AJAX 请求
  }
  static getDerivedStateFromProps(nextProps, prevState) {
    // 从此函数返回的对象
    // 将与当前状态合并。
  }
  componentWillUnmount(){
    // 在组件卸载之前立即调用
    // 适合清理监听器
  }
  render() {
    return (
      <div>
        Hello, {this.state.name}
      </div>
    )
  }
}

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

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

getDerivedStateFromProps – 有时您需要根据传入的 props 更新组件的状态。这是您执行此操作的生命周期方法。 它将传递 props(属性) 和 state(状态) ,并且您返回的对象将与当前 state(状态) 合并。

关于生命周期请参加官方文档状态(State) 和 生命周期React.Component API

好了,如果你坚持阅读到这里,那就太好了。我希望本教程对您有益,现在您对 React 有了一定的好感。

原文链接:https://tylermcginnis.com/reactjs-tutorial-a-comprehensive-guide-to-building-apps-with-react/


如果你觉得本文对你有帮助,那就请分享给更多的朋友
关注「前端干货精选」加星星,每天都能获取前端干货
赞(2) 打赏
未经允许不得转载:WEB前端开发 » React 教程:2018年学习 React.js 的综合指南

评论 1

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

前端开发相关广告投放 更专业 更精准

联系我们

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏