百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

开始学习React - 概览和演示教程

xsobi 2024-12-10 21:35 1 浏览

#头条创作挑战赛#

本文同步本人掘金平台的原创翻译:https://juejin.cn/post/6844903823085944846

当我刚开始学习JavaScript的时候,我就听说了React,但我承认看了它一眼,它吓到我了。我看到了看起来一堆HTML和CSS的混合思想,这不是我们一直努力避免的事情吗?React有什么了不起的?

相反,我只专注于学习原始的JavaScript,并在需要的时候使用jQuery。经过几次失败的React入门尝试之后,我终于开始了解它了,我开始明白为什么我可能想使用React而不是原始的JS或jQuery。

我试图将自己学到的内容浓缩成一个很好的介绍,以便与你分享,下面就是~

预备知识

在开始学习React之前,你应该事先了解一些事情。例如,如果你之前从没接触过JavaScript或者DOM,那么在解决React之前,你要更加熟悉它们。

下面是我认为学习React的预备知识:

  • 熟悉 HTML & CSS的基础知识
  • JavaScript 和编程的基础知识
  • 对DOM有基本了解
  • 熟悉 ES6 语法和特性
  • 全局安装了Node.js 和 npm

目标

  • 了解基本的React概念和相关术语,例如Babel,Webpack,JSX,组件,属性,状态和生命周期
  • 通过构建一个非常简单的React应用程序,以演示上面的概念。

下面是最终的相关源代码和示例。

  • View Source on GitHub
  • View Demo

React是什么?

  • React是一个JavaScript库 - 最受欢迎的库之一,在GitHub上超过100,000星星。
  • React不是一个框架(不像Angular,定位是框架)。
  • React是Facebook的开源项目。
  • React用于在前端构建用户界面UI。
  • React是MVC (Model View Controller)应用的View层。

React的最重要的方面之一是可以创建类似于自定义、可复用的HTML元素的组件,以快速有效地构建用户界面。React还使用状态state属性props来简化数据的存储和处理方式。

我们将在本文中介绍这些内容及其更多的内容,我们来开始吧。

安装

有几种安装React的方法,我将向你展示两种,以便你更好地了解它地工作方式。

静态HTML文件

第一种方法不是安装React的流行方法,也不是我们本教程其余部分的工作方式,但是如果你接触过jQuery之类的库,这将很熟悉并易于理解。如果你不熟悉Webpack,Babel和Node.js,那这将是种恐怖的入门方式。

让我们开始创建一个基本的index.html文件。我们将在头部head中加载三个CDN资源 - React,DOM和Babel。我们还将创建一个id为root的div,最后,我们将创建一个脚本script标签,你自定义的代码将存在于该标签中。

# 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">
      // React code will go here
    </script>
  </body>
</html>
复制代码

在编写本文的时,我加载的库是稳定版本的。

  • React - React顶级API
  • React DOM - 添加特定于DOM的方法
  • Babel - JavaScript编辑器,使我们可以在旧的浏览器中使用ES6+

我们应用程序的入口点是root div元素,该元素按惯例命名。你还会注意到text / babel的脚本类型,这是使用Babel所必需的。

现在,让我们编写React的第一个模块代码。我们将使用ES6类来创建一个名为App的React组件。

# index.html
class App extends React.Component {
  //...
}
复制代码

现在,我们将添加render()方法,这是类组件中唯一需要的方法,用于渲染DOM节点。

# index.html
class App extends React.Component {
  render() {
      return (
          //...
      );
  }
}
复制代码

在return内部,我们将编写简单的看起来像HTML元素的内容。请注意,我们不在此处返回字符串,因此请勿在元素周围使用引号。这称为JSX,我们将很快对其进行详细了解。

# index.html
class App extends React.Component {
  render() {
    return <h1>Hello world!</h1>
  }
}
复制代码

最后,我们将使用React DOM的render()方法将我们创建的App类渲染到HTML的root容器div中。

# index.html
ReactDOM.render(<App />, document.getElementById('root'))
复制代码

下面是index.html中完整的代码。

# 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,将看到我们创建的呈现给DOM的h1标签。

太棒了!现在你完成了这一步,你可以看到React并没有那么让人着迷。只是一些JavaScript帮助教程库,我们将其加载到HTML中。

我们出于演示目的完成了此操作,但是从这里开始,我们将使用另一种方式:Create React App。

创建React App

我刚刚使用的是将JavaScript库加载到静态HTML页面中并动态渲染React和Babel的方法不是很有效,并很难维护。

幸运的是,Facebook创建了Create React App,该环境预先配置了构建React所需要的一切。它将创建一个实时开发服务器,使用webpack自动编译React,JSX和ES6,自动为CSS文件加前缀,并使用ESLint测试和警告代码中的错误。

要设置create-react-app,你要在终端运行以下代码,该代码位于你希望项目所在的目录。请确保你安装了5.2以上版本的Node.js。

npx create-react-app react-tutorial
复制代码

安装完成之后,移至新创建的目录并启动项目。

cd react-tutorial
npm start
复制代码

运行此命令之后,新的React应用程序将在浏览器的localhost:3000弹出一个新窗口。

如果你查看项目结构,将会看到/public和/src目录,以及常规的node_modules,.gitignore,README.md和package.json。

在/public中,我们的重要文件是index.html,它与我们之前制作的静态index.html文件非常类似 - 只是一个root 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,我只是将原始Primitive CSS 的内容复制并粘贴到文件中。如果需要,可以使用Bootstrap或所需的任何CSS框架,或者什么都不用。我只是觉得更容易使用而已。

在index.js中,我引入了React,ReactDOM和CSS文件。

# src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
复制代码

让我们再次创建我们的App组件。以前,我们只有一个<h1>,但是现在我还要添加一个带有类的div元素。你会注意到,我们使用的是className而不是class。这是我们的第一个提示,此处编写的代码是JavaScript,而不是HTML。

# src/index.js
class App extends Component {
  render() {
    return (
      <div className="App">
        <h1>Hello, React!</h1>
      </div>
    )
  }
}
复制代码

最后,我们像之前一样渲染App到根节点中。

# src/index.js
ReactDOM.render(<App />, document.getElementById('root'))
复制代码

下面是完整的index.js代码。这次,我们将Component加载为React的属性,因此我们不再需要扩展React.Component。

# src/index.js
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开发者工具

有一个名为React Developer Tools的扩展工具,可以使你在使用React时的工作更加轻松。在你喜欢使用的任何浏览器中下载 React DevTools for Chrome。

安装后,当你打开DevTools时,你将看到React的标签。单击它,你将能够在编写组件时检查它们。你仍然可以转到elements选项卡以查看实际的DOM输出。现在看来似乎没什么大不了的,但是随着应用程序变得越来越复杂,使用它的必要性将越来越明显。

现在,我们拥有了实际开始使用React所需的所有工具和安装设置。

JSX: JavaScript + XML

正如你所见,我们在React代码中一直使用看起来像HTML的东西,但是它并不是完全的HTML。这是JSX,代表JavaScript XML。

使用JSX,我们可以编写类似HTML的内容,也可以创建和使用自己的类似XML的标签。下面是JSX赋值给变量的样子。

# JSX
const heading = <h1 className="site-heading">Hello, React</h1>
复制代码

编写React并非必须使用JSX。它在后台运行createElement,它使用标签,包含属性的对象和子组件并呈现相同的信息。下面的代码具有和上面使用JSX语法相同的输出。

# No JSX
const heading = React.createElement('h1', { className: 'site-heading' }, 'Hello, React!')
复制代码

JSX实际上更接近JavaScript,而不是HTML,因此在编写时需要注意一些关键区别。

  • 因为class被作为JavaScript中的保留关键字,className用来替代class添加CSS类。
  • JSX中的属性和方法是驼峰式的 - onclick将变为onClick
  • 自动闭合标签必须以斜杆结尾 - 例如<img />

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

const name = 'Tania'
const heading = <h1>Hello, {name}</h1>
复制代码

JSX比原始的JavaScript中创建和添加许多元素更容易编写和理解,这也是人们如此热爱React的原因之一。

组件

到目前为止,我们创建了一个组件 - App组件。React中几乎所有内容都由组件组成,这些组件可以是类组件简单组件

大多数React应用程序都是许多小组件,所有内容都加载到主要的App组件中。组件也经常有自己的文件,因此让我们更改项目。

移除index.js中的App类,它现在长这样:

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

ReactDOM.render(<App />, document.getElementById('root'))
复制代码

我们将创建一个名为App.js的新文件,然后将组件放在那里。

# src/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.js,并用以下数据填充它。

# src/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导入到其中:

# src/App.js
import Table from './Table'
复制代码

然后通过将其加载到App的render()中,然后获得Hello, React!。我还更改了外部容器的类。

# src/App.js
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 ,我们将其拆分为两个简单的组件 - 表头和表体。

我们将使用ES6箭头函数功能来创建这些简单的组件。首先是表头。

# src/Table.js
const TableHeader = () => {
  return (
    <thead>
      <tr>
        <th>Name</th>
        <th>Job</th>
      </tr>
    </thead>
  )
}
复制代码

然后是表体:

# src/Table.js
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文件如下所示。请注意,TableHeader和TableBody组件都在同一个文件中,并且由Table类组件使用。

# src/Table.js
const TableHeader = () => { ... }
const TableBody = () => { ... }

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

之后,一切都像之前那样展示。如你所见,组件可以嵌套在其他组件中,并且简单组件类组件可以混合使用。

一个类组件必须包括 render(),并且返回只能返回一个父组件。

作为总结,让我们来比较一个简单组件和一个类组件

# Simple Component
const SimpleComponent = () => {
  return <div>Example</div>
}
复制代码
# Class Component
class ClassComponent extends Component {
  render() {
    return <div>Example</div>
  }
}
复制代码

请注意,如果return的内容包含在一行中,则不需要括号。

Props属性

现在,我们有了一个很棒的Table组件,但是数据正在被硬编码。关于React的重要问题之一是如何处理数据,是通过属性(称为props)和状态(state)来处理数据。现在,我们将专注于使用props来处理数据。

首先,我们将TableBody组件的数据移除。

# src/Table.js
const TableBody = () => {
  return <tbody />
}
复制代码

然后,将所有数据移到对象数组中,就像我们引入基于JSON的API一样。我们必须在render()内部创建此数组。

# src/App.js
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变量,由于它是JavaScript表达式,因此用大括号括起来。

# src/App.js
return (
  <div className="container">
    <Table characterData={characters} />
  </div>
)
复制代码

现在,数据已经传递给Table,我们要做得是在另一边接收数据。

# src/Table.js
class Table extends Component {
  render() {
    const { characterData } = this.props

    return (
      <table>
        <TableHeader />
        <TableBody characterData={characterData} />
      </table>
    )
  }
}
复制代码

如果你打开React DevTools,然后观测Table组件,你将看到一个数组数据在其属性上。此处存储的数据称为虚拟DOM,这是一种将数据与实际DOM同步快速有效的方法。

但是,此数据尚未在实际的DOM中。在表格中,我们可以通过this.props访问所有属性。我们仅传递一个属性characterData,因此我们将使用this.props.characterData来检索该数据。

我将使用ES6属性的简写来创建一个包含this.props.characterData的变量。

const { characterData } = this.props
复制代码

因为,我们的Table组件实际上由两个小的简单组件组成,因此我将再次通过props将其传递给TableBody。

# src/Table.js
class Table extends Component {
  render() {
    const { characterData } = this.props

    return (
      <table>
        <TableHeader />
        <TableBody characterData={characterData} />
      </table>
    )
  }
}
复制代码

现在,TableBody不带任何参数并返回单个标签。

# src/Table.js
const TableBody = () => {
  return <tbody />
}
复制代码

我们将把props作为参数传递,并通过map返回数组中每个对象的表行。该映射(map)将包含在rows变量中,我们将其作为表达式返回。

# src/Table.js
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中创建列表时,应始终使用key(键),因为它们有助于识别每个列表项。我们还将在需要操纵列表项的时刻看到这是必要的。

Props是将现有数据传递到React组件的有效方法,但是该组件无法更改属性 - 它们是只读的。在下一节中,我们将学习如何使用state来进一步控制React中的数据处理。

state状态

现在,我们将字符数据存在变量的数组中,并将其作为props传递。这是一个很好的开始,但是请想象下,如果我们希望能够从数组中删除一个项目。使用props,我们有了一种单向数据流;但是有了状态state,我们可以更新组件中的私有数据。

你可以将状态state视为无需保存或修改,而不必添加到数据库中的任何数据 - 例如,在确认购买之前,在购物车中添加和删除商品。

首先,我们将创建一个状态state对象。

# src/App.js
class App extends Component {
  state = {}
}
复制代码

该对象将包含你需要在状态中存储的所有内容属性。对我们来说,就是characters。

# src/App.js
class App extends Component {
  state = {
    characters: [],
  }
}
复制代码

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

# src/App.js
class App extends Component {
  state = {
    characters: [
      {
        name: 'Charlie',
        // the rest of the data
      },
    ],
  }
}
复制代码

我们的数据已正式包含在state中。由于我们希望能够从表格中删除字符,因此我们将父App类上创建removeCharacter方法。

要检索状态,我们将使用与以前相同的ES6方法获取this.state.characters。要更新这个状态,我们使用this.setState(),这是一种用于处理状态state的内置方法。我们将根据传递的索引index过滤filter数组,然后返回新数组。

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

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

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

filter不会突变,而是创建一个新数组,并且是在JavaScript中修改数组的首选方法。这种特殊的方法是测试索引与数组中的所有索引,并返回除传递的索引之外的所有索引。

现在,我们必须将该函数传递给组件,并在每个可以调用该函数的字符旁边绘制一个按钮。我们将removeCharacter函数作为Table的属性。

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

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

由于我们将其从Table传递到TableBody,因此我们将不得不像props一样再次将其作为属性传递。

另外,由于事实证明,在我们的项目中仅由其自己的状态的组件是App和Form,因此最佳实际是将Table从当前的类组件转换为简单的组件。

# src/Table.js
const Table = (props) => {
  const { characterData, removeCharacter } = props;

  return (
    <table>
      <TableHeader />
      <TableBody characterData={characterData} removeCharacter={removeCharacter} />
    </table>
  );
}
复制代码

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

# src/Table.js
<tr key={index}>
  <td>{row.name}</td>
  <td>{row.job}</td>
  <td>
    <button onClick={() => props.removeCharacter(index)}>Delete</button>
  </td>
</tr>
复制代码

onClick 函数必须通过一个返回 removeCharacter() 方法的函数,否则它将尝试自动运行。

太棒了,现在我们有了删除按钮,我们可以通过删除字符来修改状态。

我删除了Mac数据。

现在,你应该了解如何初始化状态以及如何修改状态了。

提交表单数据

现在,我们已经将数据存储在状态中,并且可以从状态中删除任何项目。但是,如果我们希望能够添加新数据来到状态呢?在现实世界的应用程序中,你更有可能从空状态开始添加,例如代办事项列表或购物车。

开始前,我们从state.characters中删除所有的硬编码的数据,因此我们现在将通过表单进行更新。

# src/App.js
class App extends Component {
  state = {
    characters: [],
  }
}
复制代码

现在,让我们继续在一个名为Form.js的新文件中创建一个Form组件。我们将创建一个类组件,并在其中使用一个constructor(),到目前为止,我们还没做过。我们需要constructor()来使用它,并接收父项的props。

我们将把Form的初始状态设置为具有一些空属性的对象,并将该初始状态分配给this.state。

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

class Form extends Component {
  constructor(props) {
    super(props)

    this.initialState = {
      name: '',
      job: '',
    }

    this.state = this.initialState
  }
}
复制代码

我们对此表单的目标是,每次在表单中更改字段时都会更新Form的状态,并且在我们提交时,所有这些数据将传递到App状态,然后App状态将更新Table。

首先,我们将使该函数在每次对输入进行更改时都将运行。event将传递,我们将设置Form的状态为输入name(键)和value(值)。

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

  this.setState({
    [name]: value,
  })
}
复制代码

在继续提交表单之前,我们需要这个运行起来。在渲染中,让我们从state中获取两个属性,并将它们分配为正确的表单键对应的值。我们将把handleChange()作为输入的onChange运行,最后导出Form组件。

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

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

export default Form;
复制代码

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

# src/App.js
return (
  <div className="container">
    <Table characterData={characters} removeCharacter={this.removeCharacter} />
    <Form />
  </div>
)
复制代码

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

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

# src/App.js
handleSubmit = character => {
  this.setState({ characters: [...this.state.characters, character] })
}
复制代码

确保我们将其作为Form上的参数传递。

<Form handleSubmit={this.handleSubmit} />
复制代码

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

# src/Form.js
submitForm = () => {
  this.props.handleSubmit(this.state)
  this.setState(this.initialState)
}
复制代码

最后,我们将添加一个提交按钮以提交表单。因为我们没有使用标准的提交功能,我们我们使用的是onClick而不是onSubmit。点击将调用我们刚才创建的submitForm。

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

就是这样!该应用程序已经完成了。我们可以在表中创建,添加和删除用户。由于Table和TableBody已经从状态中拉出,因此将正确显示。

如果你有疑问,你可以在我的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-import App from './Api';,即可在我们创建的应用程序与该测试文件之间切换。

我不会逐行解释此代码,因为我们已经学习了有关通过状态数组来创建组件,渲染和映射的知识。此代码的新方面是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组件的更多信息。

*维基百科搜索选项可能不是随机的。 这可能是我在2005年率先发表的文章。

构建和发布一个React应用

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

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

npm run build
复制代码

这将build一个包含你的应用程序的构建文件夹。将文件夹放在你想要的位置就可以了。

我们可以更进一步,让npm为我们部署。我们将构建Github pages,因此你必须熟悉Git并在Github上获取代码。

确保你已经退出本地React环境,因此该代码未在当前运行。首先,我们要在package.json中添加一个homepage字段,其中包含我们希望应用程序继续存在的URL。

# package.json
"homepage": "https://taniarascia.github.io/react-tutorial",
复制代码

我们也需要将下面的两行代码添加到scripts的属性中。

# package.json
"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
复制代码

完成部署后,你可以通过https://taniarascia.github.io/react-tutorial 查看。

总结

本文很好地向你介绍了React,简单组件和类组件,状态,属性,使用表单数据,从API提取数据以及部署应用程序。使用React还有更多的东西要学习和实践,但是我希望你现在有足够的信心钻研React并学下去。

相关推荐

斗鱼针针成旻云个人资料 针针年龄身高演艺经历介绍

[闽南网]针针成旻云曾是七煌旗下签约艺人,经常在斗鱼进行直播身高超过170cm的她更因为有一双大长腿而被称为“斗鱼第一美腿”、“电竞第一腿”。本文这就来对针针的个人资料进行详细介绍,想知道她的年龄身高...

轻量级RTSP服务模块和RTSP推流模块适用场景区别

好多开发者一直搞不清轻量级RTSP服务SDK和RTSP推流SDK的区别,以下是相关区别:1.轻量级RTSP服务模块:轻量级RTSP服务解决的核心痛点是避免用户或者开发者单独部署RTSP或者RTMP服...

《新·奥特曼》11月18日国内视频平台上线

《新·奥特曼》海报。新京报讯11月14日,由上海新创华文化发展有限公司授权引进电影《新·奥特曼》宣布正式定档11月18日(周五)00:00上线视频平台,上线版本为日语配音中文字幕版。影片由庵野秀明(...

剑指Apple Watch!Android Wear也将支持视频功能

想必智能手表发展到现在,大家最期待的还是视频功能,近日AndroidWear就实现了这一功能,以后就能在手表上看视频了,想想就挺激动的,快来看看吧!其实早在WWDC大会上,老对手AppleWatc...

QT应用编程:基于VLC开发音视频播放器(句柄方式)

一、环境介绍操作系统:win1064位QT版本:QT5.12.6编译器:MinGW32VLC版本:...

OBS 源码分析 obs开发

本文将按照数据源的获取、渲染、推送的直播流程来让大家深入了解一下。1、直播源数据获取obs在启动时会优先加载libobs核心库,这个库初始化obs很多内容,包括crash模块、com、性能监...

Android和iOS端Moments更新:支持视频分享功能

Moments是社交网络巨头Facebook推出的一款私人照片分享应用,今天公司宣布对Android端和iOS端应用同时升级,新增对视频分享功能的支持。事实上早在数周之前,Facebook就曾表示Mo...

您很快就可以在Android Galaxy设备之间传输视频通话

在阅读此文之前,辛苦点击右上角的“关注”,既方便您进行讨论与分享,又能给您带来不一样的参与感,感谢您的支持!导语:在科技领域,每时每刻都有新的发展,令人兴奋的创新不断涌现。早在八月份,Android系...

一篇文章带你FFmpeg到流媒体服务器开发

安装ffmpeg:下载FFmpeg和libx264的包ffmpeg-2.4.1.tar.bz2last_x264.tar.bz2libx264需要yasm,所以先安装yasmapt-getinst...

YouTube 为 Android 平台提供 1440P 视频

安锋网8月10日消息,Android从起初的480P的屏幕分辨率发展到2014年的1440P花了将近六年的时间,一般认为1080P的屏幕分辨率已经是人眼可以识别的极限,但是...

FFmpeg 调用 Android MediaCodec 进行硬解码(附源码)

FFmpeg在3.1版本之后支持调用平台硬件进行解码,也就是说可以通过FFmpeg的C代码去调用Android上的MediaCodec了。在官网上有对应说明,地址如下:trac....

Android FFmpeg + OpenGL ES YUV Player

1、FFmpeg解出YUV帧数据1.1方法介绍打开封装格式上下文...

基于WebRTC的Android移动端无线视频传输

摘要:视频传输技术在现代社会广泛应用,人们对其的要求也越来越高,其发展的趋势是方便、快捷、随时随地。传统的视频传输过于依赖线路,线路的走向限制了传输的很多可能,所以无线传输才是发展的方向。本文提出...

使用python爬取抖音app视频 python爬取抖音视频数据

记录一下如何用python爬取app数据,本文以爬取抖音视频app为例。编程工具:pycharm...

Android IOS WebRTC 音视频开发总结(七七)-- WebRTC的架构和协议栈

本文主要介绍WebRTC的架构和协议栈(我们翻译和整理的,译者:litie),最早发表在【编风网】为了便于理解,我们来看一个最基本的三角形WebRTC架构(见下图)。在这个架构中,移动电话用“浏览器M...