【译】React入门导学与实战

关于本译文,我的小说明:

最近在学习React,看到这篇特别详细的入门文章,觉得很棒,就想赶在青年节结束之前,翻译并分享出来。这是本人第一篇技术译文,即便花费了好几天时间,也还是可能存在一些翻译不到位的地方。如果可爱的你发现了什么错误,别被我误导,以原文的意思为准~😸😸😸


以下为正文:

当我第一次开始学JavaScript时,就已经听说过React了。

但我得承认,当我看了一眼React后,我就被吓到了:我看到一堆与JavaScript混合在一块儿的HTML,心想,这种形式不是我们应该避免的吗?React有啥了不起的地方?

作为代替,我只专注于学习原生JS,并在专业的环境下使用jQuery。经过一些迷茫、失败的尝试之后,我最终开始明白,为什么我或许更想使用React而非原生JS或jQuery。

前提条件

以下是一些你在开始玩转React之前需要提前了解的东西。举个例子,如果你之前从来都没有使用过JavaScript或者DOM,那么在尝试使用React之前,最好先熟悉了解这些基础知识。

• 熟悉HTML&CSS
• 了解JavaScript及其语法
• 理解DOM
• 熟悉Es6语法及其特性
• 全局安装了Node.jsnpm

目标
  • 了解React基本的概念及术语。比如Babel、Webpack、JSX、组件、props、state以及生命周期
  • 创建一个能演示上述概念的简单Reac应用程序

以下是最终需要完成的Reac应用程序的资源和在线demo地址:

什么是React?
  • React是一个受欢迎的JavaScript库,在Github上拥有超过100,000个的star
  • React不是一个框架(与Angular不同,React更偏向自用)
  • React是一个由Facebook创建的开源项目
  • React是MVC应用程序((Model、View、Controller))中的view层

React最重要的一个方面就是你可以创建自定义、可重复利用的组件,并用来快速高效的构建用户界面。React也通过使用stateprops精简了数据被存储和处理的过程。

引入React

有好几种引入React的方式,我会向你展示其中的两种,以便你能更好地了解它的运作方式。

静态HTML文件

第一种引入React的方法并不常用,也不是我们将在本文中重点实践的。但如果你曾经使用过jQuery之类的库,那么这种方式就会很容易理解。而且,如果你不熟悉Webpack,Babel和Node.js,这是最不可怕的入门方法。

让我们从创建一个基础的index.html文件开始。

head中通过引入CDN的方式,引入React、React DOM以及 Babel.

然后创建一个div,为之添加一个名为root的id;最后,再创建一个script标签,用来编辑你的自定义代码。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Hello React!</title>
    <script src="https://unpkg.com/react@^16/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@16.13.0/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
  </head>

  <body>
    <div id="root"></div>
    <script type="text/babel">
      // React code will go here
    </script>
  </body>
</html>

我在写这篇文章时,以下依赖我使用的是最新的稳定版本:

  • React - React顶级API
  • React DOM - 增加与DOM相关的方法
  • Babel - 一个JavaScript解析器–能让我们在旧版的浏览器中使用ES6+语法

我们的应用程序的入口点是之前创建的div元素,该元素按照惯例命名。你也会注意到script的类型是text/babel,这是在使用Babel时必须添加的。

现在,我们来编写React的第一个代码块。我们将使用ES6中的类来创建一个React组件,称作App

class App extends React.Component {
  //...
}

接下来添加render()方法,这是唯一一个在类组件中需要使用的方法,用于渲染DOM节点。

class App extends React.Component {
  render() {
      return (
          //...
      );
  }
}

return中,我们将放入一段看起来像简单HTML节点的代码块。

注意,在这里并不是要返回一个字符串,所以不要在元素周围使用引号。

这种语法称作JSX,我们很快会学到更多相关的东西。

class App extends React.Component {
  render() {
    return <h1>Hello world!</h1>
  }
}

最后,我们使用React DOM的render()方法将我们创建的App类渲染至HTML的节点div中。

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

以下是index.html中的完整代码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Hello React!</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
  </head>

  <body>
    <div id="root"></div>

    <script type="text/babel">
      class App extends React.Component {
        render() {
          return <h1>Hello world!</h1>
        }
      }

      ReactDOM.render(<App />, document.getElementById('root'))
    </script>
  </body>
</html>

现在如果你在浏览器中访问index.html,你会看见我们创建的h1标签已经被渲染到了DOM中。

棒棒哒! 现在你已经完成了这一步,你会发现入门React并没有那么的吓人。它只是一些我们能将其加载到HTML中的JavaScript辅助库。

用这种方式我们已经完成了演示应用程序的目标,但除此之外,我们还可以使用另一种引入react的方法: Create React App.

Create React App

上述使用的方法是将JavaScript库加载至静态HTML文件中,并实时渲染React和Babel。这种方式并不高效,而且代码也很难维护。

幸运的是,Facebook支持通过Create React App这种方式来构建React App,这种方式预先配置了构建React应用所需的所有依赖项。

Create React App会创建一个实时的开发服务器,使用Webpack来自动编译React、JSX、ES6以及自动给CSS文件增加前缀。此外,它还会使用ESLint测试代码并告警代码中的错误。

在终端运行以下代码以安装create-react-app,项目所在目录由你自己决定

npx create-react-app react-tutorial

安装成功后,进入刚才新建的项目目录里,并运行项目

cd react-tutorial
npm start

当你执行上述命令后,你新创建的React app将会运行在新浏览器窗口localhost:3000

Create React App 很适合初学者以及大型企业应用使用,但并不适合所有情况。你也可以为React创建自己的Webpack设置。

如果你查看项目的结构,你会看到/public/src文件夹,还有常见的node_modules, .gitignore, README.md以及 package.json

/public目录中,最重要的文件是index.html,它与我们前面创建过的静态HTML文件index.html很相似—只有一个div。

但这次,没有库或者脚本被加载,/src目录会包含项目所有的React代码。

为了了解运行环境是如何自动编译并更新React代码的,在src目录下的App.js文件中找到下面这行文本。

To get started, edit `src/App.js` and save to reload.

用任何其它文本代替该内容,一旦你保存了该文件,你会发现localhost:3000编译并自动刷新为了新内容。

删除/src文件夹外的所有文件,只保留index.css以及index.js,我们将会创建自己的模板文件,而且看起来不会很臃肿。

对于index.css,我为了操作起来简单,只是将原生的CSS粘贴复制到文件里了,如果你需要的话,你可以使用BootStrap或者其他任何你需要的CSS框架,或者啥都不用。

index.js中,引入React、ReactDOM以及index.css

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'

让我们再次来创建App组件吧。之前的例子里,只有一个h1标签,但现在我还添加了一个带有类的div。你会发现代码中使用的是className而非class这是第一个暗示:我们此处编写的代码是JavaScript,而不是HTML。

class App extends Component {
  render() {
    return (
      <div className="App">
        <h1>Hello, React!</h1>
      </div>
    )
  }
}

最后,和之前一样,将App渲染至根节点中。

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

下面是index.js中的完整代码,这次,我们将Component作为React的一个属性加载,因此extends后面不再需要写成 React.Component

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './index.css'

class App extends Component {
  render() {
    return (
      <div className="App">
        <h1>Hello, React!</h1>
      </div>
    )
  }
}

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

如果你现在查看localhost:3000,你会和之前一样,看见"Hello, React!"
现在我们已经有了构建一个React应用程序的开端。

React Developer Tools

React Developer Tools是一个扩展工具,它能帮助你更轻松的调试React。下载Chrome下的React Developer Tools,或者在其他你更喜欢的浏览器下载。

安装完之后,打开谷歌开发者工具(DevTools),你会看见一个React的标签页。点击这个选项卡,你就能够在编写组件时在DevTools中检查它们。

你也可以在Elements的选项卡中,查看真实的DOM输出。现在看起来这个工具并没有起多大作用,但是当你的React应用程序变得越来越复杂时,使用该工具就会变得愈加重要。


截止现在,我们已经有了所有开始使用React的配置和工具。

JSX: JavaScript + XML

正如你看到的那样,我们在React代码中使用了看起来像HTML的代码,但它其实并不是HTML。这种语法称为JSX,指的是JavaScript XML。

我们可以使用JSX编写类似于HTML的内容,也可以自定义类XML标签。

下面是JSX赋值给一个变量的例子:

const heading = <h1 className="site-heading">Hello, React</h1>

React并不强制你使用JSX,每个 JSX 元素只是调用 React.createElement(component, props, …children) 的语法糖。

下面的代码会和JSX有相同的输出结果:

const heading = React.createElement('h1', { className: 'site-heading' }, 'Hello, React!')

JSX更接近于JS,而非HTML。因此在编写JSX时有一些关键的不同点需要注意:

  • 增加css类时,应该使用className而非class,因为class在JS中是一个保留关键字。
  • JSX中的属性和方法的命名遵循小驼峰法。(onclick应该变为onClick)
  • 自闭合的标签必须以/结尾.例如,<img />

JavaScript表达式也可以使用大括号(包括变量,函数和属性)嵌入JSX内。

const name = 'Tania'
const heading = <h1>Hello, {name}</h1>

JSX比原生JS更容易编写和理解,这也是React如此受人们喜欢的原因之一。

组件

截止现在,我们已经创建了一个名为App的组件,React中几乎所有东西都由组件构成,组件可以是类组件或者简单组件。

大多数React应用程序都有很多小组件,所有小组件都会被加载到主要的App组件中。组件通常也会有自己的文件,所以让我们来改变项目的结构:

index.js中移除App类,代码会变成这样:

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import './index.css'

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

接下来,创建一个叫做App.js的文件,并放入组件:

import React, { Component } from 'react'

class App extends Component {
  render() {
    return (
      <div className="App">
        <h1>Hello, React!</h1>
      </div>
    )
  }
}

export default App

将组件导出为App,并在index.js中加载它。将组件拆分为文件并不是必须的,但是如果不这样做的话,应用程序就会变得臃肿和混乱。

类组件

让我们创建另一个Table组件。新建Table.js文件,并编写如下代码:

import React, { Component } from 'react'

class Table extends Component {
  render() {
    return (
      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Job</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Charlie</td>
            <td>Janitor</td>
          </tr>
          <tr>
            <td>Mac</td>
            <td>Bouncer</td>
          </tr>
          <tr>
            <td>Dee</td>
            <td>Aspiring actress</td>
          </tr>
          <tr>
            <td>Dennis</td>
            <td>Bartender</td>
          </tr>
        </tbody>
      </table>
    )
  }
}

export default Table

这个组件通常称为类组件,自定义组件的命名需要大写,以此来和普通的HTML元素作区分。

回到App.js文件,我们可以在其中加载Table组件了,第一步,引入它:

import Table from './Table'

然后将其加载到Apprender()中,位置是之前我们放置"Hello,React"的地方。我也更改了div容器的类名。

import React, { Component } from 'react'
import Table from './Table'

class App extends Component {
  render() {
    return (
      <div className="container">
        <Table />
      </div>
    )
  }
}

export default App

如果你查看浏览器,你会发现Table组件已经被成功加载进去了。


现在,我们了解了一个常规的类组件的写法。我们可以重复利用这个组件。但是,由于数据已经被硬编码到该组件中了,所以目前来说它并没有多大用处。

简单组件(函数组件)

React中组件的另一种类型是简单组件,它本质上是一个函数。这种类型的组件不使用class关键字。

我们在Table组件中编写两个简单的组件:一个表头( table header)、一个表体(table body)

我们将使用ES6的箭头函数来创建这两个组件。首先,创建表头组件:

const TableHeader = () => {
  return (
    <thead>
      <tr>
        <th>Name</th>
        <th>Job</th>
      </tr>
    </thead>
  )
}

然后创建表体组件:

const TableBody = () => {
  return (
    <tbody>
      <tr>
        <td>Charlie</td>
        <td>Janitor</td>
      </tr>
      <tr>
        <td>Mac</td>
        <td>Bouncer</td>
      </tr>
      <tr>
        <td>Dee</td>
        <td>Aspiring actress</td>
      </tr>
      <tr>
        <td>Dennis</td>
        <td>Bartender</td>
      </tr>
    </tbody>
  )
}

现在,Table文件看起来应该是这样:

const TableHeader = () => { ... }
const TableBody = () => { ... }

class Table extends Component {
  render() {
    return (
      <table>
        <TableHeader />
        <TableBody />
      </table>
    )
  }
}

注意,TableHeader以及TableBody组件都在同一个文件中,并且会被类组件Table使用。

如你所见,组件可以被嵌套在其它组件中,而且简单组件、类组件可以混合使用。

类组件必须包含render(),且只能返回一个父元素。

最后,我们来简单比较一下函数组件和类组件:

函数组件:

const SimpleComponent = () => {
  return <div>Example</div>
}

类组件:

class ClassComponent extends Component {
  render() {
    return <div>Example</div>
  }
}

注意,如果return的内容只有一行,则不需要使用括号。

Props

现在我们已经有了一个很棒的Table组件,但是数据被硬编码了。学习React时,一个很重要的问题就是了解它是如何处理数据的。React通过属性(称为props)以及状态来处理数据。

现在,我们先来关注如何使用props来处理数据:

首先,将TableBody组件中先前的数据全部删掉,只保留下面的部分:

const TableBody = () => {
  return <tbody />
}

然后将刚才被移除的数据移动到一个对象数组中,这与引入一个基于JSON的API类似。这个对象数组需要在render里面创建。

class App extends Component {
  render() {
    const characters = [
      {
        name: 'Charlie',
        job: 'Janitor',
      },
      {
        name: 'Mac',
        job: 'Bouncer',
      },
      {
        name: 'Dee',
        job: 'Aspring actress',
      },
      {
        name: 'Dennis',
        job: 'Bartender',
      },
    ]

    return (
      <div className="container">
        <Table />
      </div>
    )
  }
}

接下来,我们将通过属性将数据传递给子组件(Table),类似于使用data属性来传递数据。

属性名称可以命名为任何非关键字的名称,在这里,我将其命名为characterData。我传递的数据是`characters,由于characters是变量,所以需要用大括号括起来。

return (
  <div className="container">
    <Table characterData={characters} />
  </div>
)

现在数据已经被传递进Table组件中了,我们必须在另一端(Table组件中)进行访问。

class Table extends Component {
  render() {
    const { characterData } = this.props

    return (
      <table>
        <TableHeader />
        <TableBody characterData={characterData} />
      </table>
    )
  }
}

打开React DevTools并检查Table组件,你会在属性中看到含有数据的数组。被存储在这里的数据称为虚拟DOM—一种可以快速高效的将数据与真实DOM同步的方法。

但是,这里的数据尚未存储在真实DOM中,在Table组件中,我们可以通过this.props访问所有的props属性。在这里,我们只需要传递一个名为characterData的prop,通过this.props.characterData来获取数据。

我将使用ES6语法来创建一个包含this.props.characterData的变量:

const { characterData } = this.props

既然Table组件是有两个简单组件组成的,我将再一次通过传递props来将数据传入TableBody组件里。

class Table extends Component {
  render() {
    const { characterData } = this.props

    return (
      <table>
        <TableHeader />
        <TableBody characterData={characterData} />
      </table>
    )
  }
}

TableBody组件目前没有携带任何参数,并返回单个标签。

const TableBody = () => {
  return <tbody />
}

现在,将props作为TableBody组件的参数,遍历characterData数组,并将数组中的每项值作为表格的行数据返回。

遍历结果将包含在rows变量中,并以表达式的形式返回。

const TableBody = props => {
  const rows = props.characterData.map((row, index) => {
    return (
      <tr key={index}>
        <td>{row.name}</td>
        <td>{row.job}</td>
      </tr>
    )
  })

  return <tbody>{rows}</tbody>
}

如果你现在查看应用程序的前端界面,你会发现所有数据已经被加载进去了。

或许你已经注意到,我给每个表格的行上添加了一个键索引。 在React里创建列表时,都需要使用键,因为它们有助于识别每个列表项。 在你需要操作列表的每一项时,就会知道这么做的原因。

props是一种高效的向React组件传递数据的方式,但组件不能修改props,因为props是只读的。在下面的内容中,我们将会了解到,在React中如何使用状态(state)来更进一步的控制数据的。

状态(state)

我们已经将characterData以数组形式存储在一个变量中,并且通过props传递它。这是一个好的开端,但如果我们想删除数组中的某一项,使用props,会受到单向数据流的限制。然而,使用state,我们就能够更新组件中的私有数据。

你可以将state视为任何需要进行保存或修改的数据,这些数据不需要被添加到数据库中。这与你在确认购买东西之前,在购物车中添加和删除商品的操作类似。

让我们创建一个state对象:

class App extends Component {
  state = {}
}

这个对象可以包含所有你想存储到state中的数据。对我们来说,需要存储的数据是characters

class App extends Component {
  state = {
    characters: [],
  }
}

将我们先前创建的整个对象数组移到state.characters中。

class App extends Component {
  state = {
    characters: [
      {
        name: 'Charlie',
        // the rest of the data
      },
    ],
  }
}

我们所需要的数据已经正式包含在了state中,既然我们想要从表格中删除一项数据,我们可以在App组件中创建一个removeCharacter方法。

为了获取state,我们将和先前一样,使用ES6语法来获取this.state.characters

我们可以使用this.setState()(React处理状态的内置方法)来更新state,我们将根据索引值过滤数组,并返回新数组。

你必须使用this.setState()修改数组。仅将新值应用于this.state.property并不会起作用。

//App.js
removeCharacter = index => {
  const { characters } = this.state

  this.setState({
    characters: characters.filter((character, i) => {
      return i !== index
    }),
  })
}

filter方法不会改变原数组,它返回过滤后的新数组。它是一个在JS中修改数组的好方法。(filter 为数组中的每个元素调用一次回调函数函数,并返回一个由通过测试的元素组成的数组)

接下来,需要将removeCharacter函数传递给组件,并在每个可以调用该函数的字符旁边绘制一个按钮。我们将通过prop的方式传递removeCharacter函数。

//App.js
render() {
  const { characters } = this.state

  return (
    <div className="container">
      <Table characterData={characters} removeCharacter={this.removeCharacter} />
    </div>
  )
}

现在,我们已经将removeCharacterTable组件传递到了TableBody中,我们需要再次使用props的方式来传递removeCharacter,与传递characterData类似。

此外,在我们的项目中,拥有自身状态的组件为AppForm组件,将Table组件由当前的类组件转换为函数组件,会是一次不错的实战。

//Table.js
const Table = props => {
  const { characterData, removeCharacter } = props

  return (
    <table>
      <TableHeader />
      <TableBody characterData={characterData} removeCharacter={removeCharacter} />
    </table>
  )
}

下面就是我们在removeCharacter()方法中定义的索引的输入位置。在TableBody组件中,我们将把键/索引作为参数传递,因此过滤器函数需要知道哪一项需要被删除。 我们将创建一个带有onClick函数的按钮并将其传递:

<tr key={index}>
  <td>{row.name}</td>
  <td>{row.job}</td>
  <td>
    <button onClick={() => props.removeCharacter(index)}>Delete</button>
  </td>
</tr

OnClick函数必须通过一个返回removeCharacter方法的函数传递,否则OnClick将会尝试自动执行。

现在我们已经有了删除按钮,而且能够通过删除一个字符来修改state

我删除了表格中名为Mac的那行数据。

现在你应该已经能理解状态是如何初始化的,以及是如何被修改的。

提交表单数据

现在,已经有数据被存储在了state中,我们也能够从state中移除数据中的任何一项。但是,如果我们想给state中增加一项数据呢?在一个真实的应用程序中,你更可能会从一个空state中入手,并往里添加数据,比如说开发一个to-do-list清单或者一个购物车功能。

首先,让我们从state.characters中删除所有硬编码的数据,因为我们现在将通过表单进行数据的更新。

//App.js
class App extends Component {
  state = {
    characters: [],
  }
}

接下来,创建一个新文件Form.js名,并在其中创建一个名为Form的组件。
将Form的初始状态设置为具有一些空属性的对象,并将该初始状态分配给this.state

//Form.js
import React, { Component } from 'react'

class Form extends Component {
  initialState = {
    name: '',
    job: '',
  }

  state = this.initialState
}

React早前的版本需要在类组件上包含constructor(),但现在不再需要了。

关于该表单,我们的目标是: 每次在表单中更改字段时都会更新Form的状态,并且在提交时,所有这些数据都将传递到App组件的state中,然后App的state将会更新表格中的数据。

首先,我们将创建一个每次对输入进行更改时都将运行的函数。 该事件被执行后,设置Form的状态为输入的名称(键)和值。

//Form.js
handleChange = event => {
  const { name, value } = event.target

  this.setState({
    [name]: value,
  })
}

在提交表单之前,我们先让这个函数可以运行。

首先,在render()里,从state中获取两个属性,并将它们分配为表单的键所对应的值。 然后运行handleChange(方法,最后,导出Form组件。

//Form.js
render() {
  const { name, job } = this.state;

  return (
    <form>
      <label htmlFor="name">Name</label>
      <input
        type="text"
        name="name"
        id="name"
        value={name}
        onChange={this.handleChange} />
      <label htmlFor="job">Job</label>
      <input
        type="text"
        name="job"
        id="job"
        value={job}
        onChange={this.handleChange} />
    </form>
  );
}

export default Form;

App.js中,我们可以在table下面渲染Form表单。

//App.js
import Form from './Form';
//App.js
return (
  <div className="container">
    <Table characterData={characters} removeCharacter={this.removeCharacter} />
    <Form />
  </div>
)

现在,如果我们转到应用程序的前端界面,将会看到尚未提交的表单。 更新一些字段,你将看到正在更新的Form的本地状态。

很棒! 最后一步是使我们能够真正提交该数据并更新父级的状态。 我们将在App上创建一个名为handleSubmit()的函数,该函数将通过使用ES6扩展运算符获取现有的this.state.characters,并添加新的character参数来更新状态。

//App.js
handleSubmit = character => {
  this.setState({ characters: [...this.state.characters, character] })
}

请确保将handleSubmit()函数作为Form组件的一个参数进行传递。

<Form handleSubmit={this.handleSubmit} />

现在在Form中,我们将创建一个名为SubmitForm()的方法,该方法将调用该函数,并将Form的state作为我们先前定义的character参数传递。 同时,在SubmitForm()方法中,将state重置为初始状态,以便在提交后清除表单。

//Form.js
submitForm = () => {
  this.props.handleSubmit(this.state)
  this.setState(this.initialState)
}

最后,增加一个提交按钮以提交表单。 由于我们没有使用标准的提交功能,所以我们使用的是onClick而不是onSubmit。 单击提交按钮,将会调用我们刚才创建的submitForm方法。

<input type="button" value="Submit" onClick={this.submitForm} />

到现在,这个应用程序就完成啦!我们能够向表格中添加以及删除用户了。由于TableTableBody已经从state中取出了,因此能够正确的在table中显示。

上述步骤中,如果你有任何疑惑的地方,可以在github上查看完整的代码示例。

获取API接口数据

React的一种非常常见的用法是从API获取数据。 如果你不了解什么是API或如何连接API,我推荐你阅读如何使用JavaScript连接API
,这篇文章会引导你了解什么是API以及如何将它们与原始JavaScript一起使用。

作为一个小测试,我们可以创建一个新的Api.js文件,并在其中创建一个新的App组件。 可以用来测试的公共API是Wikipedia API
,我这里有一个URL端点可以进行随机搜索。 你可以转到该链接查看API-并确保在浏览器上安装了JSONView

我们将使用JavaScript的内置Fetch从该URL端点收集数据并显示。 你只需更改index.js中的URL,即可在我们创建的应用程序与该测试文件之间进行切换。

我不会逐行解释下述代码,因为我们已经学习了关于通过一个状态数组,来创建组件,渲染组件以及遍历组件的知识。下述代码新引入的概念是componentDidMount(),这是React中的一种生命周期方法。 生命周期是在React中调用方法的执行顺序。 Mounting是指挂载数据至DOM的过程。

提取API数据时,我们要使用componentDidMount,因为我们要确保在导入数据之前已将组件渲染到了DOM中。 在以下代码段中,您将看到我们如何从Wikipedia API引入数据,并将其显示在页面上:

//Api.js
import React, { Component } from 'react'

class App extends Component {
  state = {
    data: [],
  }

  // Code is invoked after the component is mounted/inserted into the DOM tree.
  componentDidMount() {
    const url =
      'https://en.wikipedia.org/w/api.php?action=opensearch&search=Seona+Dancing&format=json&origin=*'

    fetch(url)
      .then(result => result.json())
      .then(result => {
        this.setState({
          data: result,
        })
      })
  }

  render() {
    const { data } = this.state

    const result = data.map((entry, index) => {
      return <li key={index}>{entry}</li>
    })

    return <ul>{result}</ul>
  }
}

export default App

在本地服务器中保存并运行此文件后,你会看到DOM中显示的Wikipedia API数据。

React还有其他的生命周期方法,但是本文不再具体讨论它们。你可以在这里了解更多有关生命周期的知识。

构建并部署React应用

到目前为止,我们所编写的一切代码都在开发环境中。 我们一直在进行即时的编译,热重载和更新。 在生产环境中,我们将会加载静态文件-没有源代码。 我们可以通过构建并部署它来做到这一点。

现在,如果你只想编译所有React代码并将其放置在某个目录的根目录中,则只需运行以下代码:

npm run build

这个命令将构建一个包含应用程序的构建文件夹。 将文件夹的内容放在任何地方,你就可以完成部署了!

我们还可以更进一步: 部署npm。 这一步我们将会构建至GitHub页面,因此你必须熟悉Git,并在GitHub上获取代码。

如果已经确保你已经退出了本地的React开发环境,那么代码当前并没有运行。 首先,在package.json中添加一个homepage字段,其中包含我们希望应用程序所在的URL。

"homepage": "https://taniarascia.github.io/react-tutorial",

再将下面这两行代码添加到scripts属性上:

"scripts": {
  // ...
  "predeploy": "npm run build",
  "deploy": "gh-pages -d build"
}

在你的项目中,可以将gh-pages添加到devDependencies里。

npm install --save-dev gh-pages

运行build命令,其中将包含所有已编译的静态文件。

npm run build

最后,部署至gh-pages上:

npm run deploy

现在我们已经完成了部署,你已经可以在taniarascia.github.io上查看这个应用程序啦~

结论

本文应该已经很好地向你介绍了React的简单/类组件、状态、props、在React中如何使用表单数据、从API提取数据以及部署应用程序。

使用React还有更多的东西要学习和实践,但是我希望你现在已经有信心钻研和玩转React了!


原文地址: https://www.taniarascia.com/getting-started-with-react/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值