本文概述和实际演练 React 的基本概念,例如组件,state(状态) 和 props(属性),以及提交表单,从 API 获取数据以及将 React 应用程序部署到生产环境。
自从我第一次开始学习 JavaScript 以来,我一直都有听说 React ,但我承认我只粗略的看了一下 React 相关内容就被吓到了。我看到一堆 HTML 和 JavaScript 混合在一起的代码,我想,这不是我们一直试图避免的吗? React 有什么大不了的?
相反,我只专注于学习原生的 JavaScript 并在专业环境中使用 jQuery 。在经历了几次失败的尝试之后,我终于开始尝试使用 React ,我开始明白了为什么我要使用 React 而不是原生的 JS 或 jQuery 。
我试着将我学到的所有内容浓缩成这篇很好的介绍文章,并与你分享。
预备知识
在开始使用 React 之前,您应该事先知道一些事情。 例如,如果您以前从未使用过 JavaScript 或 DOM ,那么在尝试使用 React 问题之前,你应该首先熟悉它们。
以下是我认为是React的先决条件。
目标
- 了解必要的 React 概念和相关术语,例如 Babel,Webpack,JSX,components(组件),props(属性),state(状态) 和 生命周期。
- 构建一个非常简单的 React 应用程序,实际演练上述概念。
本文 已经放到了GitHub上。
什么是 React ?
- React 是一个 JavaScript 库 – 最受欢迎的库之一,在 。
- React 不是一个框架(与 Angular 不同,后者更 opinionated (倾向性))。
- React 是一个由 Facebook 创建的开源项目。
- React 用于在Tian构建用户界面(UI)。
- React 是 MVC(Model View Controller,模型视图控制) 应用程序的 视图 层。
React 最重要的一个方面是,您可以创建 components(组件),类似于自定义,可重用的HTML元素,可以快速高效地构建用户界面。 React 还利用 state(状态) 和 props(属性) 简化了数据的存储和处理方式。
我们将在整篇文章中详细介绍所有这些内容,让我们开始吧。
设置和安装
设置 React 有几种方法,我会在这里告诉你种方法,这样你就可以很好地了解它是如何工作的。
静态HTML文件
第一种方法不是设置 React 的流行方式,本教程的其余部分也不是使用这个方法的,但是如果你曾经使用像 jQuery 这样的库,那么这种你将会很熟悉且易于理解,如果你不熟悉 Webpack ,Babel 和 Node.js ,那么可以使用这种最简单的方法开始。
让我们从制作一个基本的 index.html
文件开始。 我们将在头部加载三个 CDN 文件- React,React DOM 和 Babel 。 我们还将创建一个 id 为 root
的 div
元素,最后我们将创建一个 script
标签,您的自定义代码将都放在这里。
<!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/[email protected]/babel.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> // React 代码将放在这里 </script> </body> </html>
在撰写本文时,我加载的是最新的稳定版本的 React 。
- React – React 顶级 API, 。
- React DOM – 添加特定于 DOM 的方法 。
- – 一种 JavaScript 编译器,允许我们在旧浏览器中使用 ES6+
我们的应用程序的入口点将是 id 为 root
的 div
元素,它按惯例命名。 您还会注意到 text/babel
脚本类型,这对于使用 Babel 是必需的。
现在,让我们编写我们的第一个 React 代码块。 我们将使用 ES6 类来创建一个名为 App
的 React 组件。
class App extends React.Component { //... }
现在我们将添加 render()
方法,这是类组件中唯一必须的方法,用于渲染 DOM 节点。
class App extends React.Component { render() { return ( //... ); } }
在 return
内部 ,看起来像一个简单的 HTML 元素。请注意,我们不需要在此处返回 String
类型的字符串,因此请不要使用引号将元素括起来。这里的内容被称为 JSX
,我们很快将在下面的文章中了解它。 (注:这里是 ,有兴趣你可以先了解一下。)
class App extends React.Component { render() { return ( <h1>Hello React!</h1> ); } }
最后,我们将使用 React DOM 的 render()
方法将我们创建的 App
类渲染到 HTML 中的 id 为 root
的 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/[email protected]/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 中。
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。 在这里,index.html
文件中没有加载任何库或脚本。/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
,我只是将 的内容复制并粘贴到文件中。 如果需要,可以使用 Bootstrap 或任何您想要的 CSS 框架,或者根本不使用。 我发现它更容易使用。
现在在 index.js
中,我们正在导入 React,ReactDOM 和 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> ); } }
最后,我们将像以前一样将应用程序渲染到 root
div 中。
ReactDOM.render(<App />, document.getElementById('root'));
这是我们的完整 index.js
。这次,我们将 Component
作为 React 的 property(属性) 加载,因此我们不再需要扩展 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 中文文档 和 中介绍。
React 开发人员工具
React Developer Tools 扩展可以让您在使用 React 时更轻松。 下载 或您喜欢的任何浏览器。
安装后,当您打开开发人员工具时,您将看到 React 的选项卡。 单击它,您将能够在编写组件时对其进行检查。 您仍然可以转到 Elements 选项卡以查看实际的 DOM 输出。 现在看起来似乎不太合适,但随着应用程序变得越来越复杂,使用它将变得越来越必要。
现在我们拥有了实际开始使用 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 。 在底层,它其实是在执行 createElement
,它接受标签、包含属性的对象和组件的子元素,并渲染相同的信息。下面的代码将具有与上面的JSX相同的输出。
const heading = React.createElement( 'h1', {className: 'site-heading'}, 'Hello, React!' );
JSX 实际上更接近 JavaScript ,而不是 HTML ,因此在编写时需要注意几个关键的区别。
- 使用
className
代替class
来添加CSS类,因为class
是 JavaScript 中的保留关键字。 - JSX 中的属性和方法是 camelCase(驼峰命名) –
onclick
将写成onClick
。 - 自动闭合标签必须以斜线结尾 – 例如
<img />
。
JavaScript表达式也可以使用花括号嵌入到 JSX 中,包括变量,函数和属性。
const name = 'Tania'; const heading = <h1>Hello, {name}</h1> ;
JSX 比在原生的 JavaScript 中创建和附加多个元素更容易编写和理解,这也是人们喜欢React的原因之一。
更多信息请查看 React 中文文档中的 和
组件(Components)
到目前为止,我们已经创建了一个组件– App
组件。 React 中的几乎所有内容都由组件组成,组件可以是 class components(类组件)或 simple components(简单组件,注普遍的叫法为 functional components ,也就是函数式组件)。
大多数 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'));
我们将在 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;
我们将组件 export(导出) 为 App
并将其加载到 index.js
中。将组件分离到单独文件中并不是强制的,但如果不这样做,应用程序将开始变得笨拙,达到一定程度将难以维护,甚至失控。
类组件(Class Components)
让我们来创建另一个组件。 我们要创建一个表格,命名为 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;
我们创建的这个组件是一个自定义 class components(类组件)。 我们将自定义组件的首字母大写,以区别于常规 HTML 元素。 回到 App.js
,我们可以用 Table
名称来加载她,首先 import(导入) 它:
import Table from './Table';
然后将它加载到 App
的 render()
方法中,也就是把之前的 “Hello, React!” 替换掉。我还修改了外容器的样式类 container
。
return ( <div className="container"> <Table /> </div> );
如果您重新在浏览器中查看,则会看到 Table
已经被加载进来了。
现在我们已经看到了自定义类组件是什么。我们可以一遍又一遍地重用这个组件。但是,由于数据是硬编码的,因此目前不太好用。
函数式组件(Functional Components)
注:原文中的叫法是 简单组件(Simple Components),翻译的时候用了官方的叫法 functional components ,也就是函数式组件。可以查看官方文档《》 中关于 函数式组件和类组件 的描述。
React 中的另一种组件是 functional components(函数式组件),它是一个函数。这种组件不使用 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
类看起来像这样。
class Table extends Component { render() { return ( <table> <TableHeader /> <TableBody /> </table> ); } }
一切都应该像以前一样出现。如您所见,组件可以嵌套在其他组件中,并且可以混合函数式组件和类组件。
注意:类组件必须包含
render()
方法,并且return
只能返回一个父元素。
我们来比较一下 functional components(函数式组件)和 class components(类组件)。
functional components(函数式组件):
const SimpleComponent = () => { return <div>Example</div>; }
class components(类组件)
class ClassComponent extends Component { render() { return <div>Example</div>; } }
请注意,如果 return
内容包含在一行中,则不需要用花括号括起来了。
了解关于组件的更多信息请查看官方文档《》(中文)。
Props(属性)
现在,我们有了一个很好的 Table
组件,但数据是硬编码的。 React 最重要的特性之一就是处理数据的方式,它使用 props(属性) 和 state(状态) 来实现。首先,我们将重点讨论如何使用属性(props)来处理数据。
首先,让我们从 TableBody
组件中删除所有数据。
const TableBody = () => { return <tbody></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
变量,我会在它使用花括号括起来,因为它是一个 JavaScript 表达式。
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
组件,您将在属性中看到数据数组。这里存储的数据称为 virtual DOM(虚拟DOM) ,这是一种快速有效的方法,可以将数据与实际 DOM 同步。
但是,这些数据还没有被渲染到实际的 DOM 中。 在 Table
中,我们可以通过 this.props
访问所有 props(属性)。 我们通过 characterData
只传递了一个 props(属性),所以我们将使用 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></tbody>; }
我们将把 props(属性) 作为参数传递,并通过 以返回数组中每个对象的 table row (表行)。这个映射将包含在 row
变量中,我们将以表达式的形式返回这个变量。
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>; }
如果你在浏览器中查看应用程序,则现在已经加载了所有数据。
您会注意到我已经为每个 table row(表行) 添加了一个键索引。 在 React 中创建列表时应始终使用 ,因为它们有助于识别每个列表项。 当我们想要操作列表项时,我们还将看到这一点有多么的重要。
props(属性) 是将现有数据传递给 React 组件的有效方法,但是组件不能更改 props(属性) – 它们是只读的。 在下一节中,我们将学习如何使用 state(状态) 来进一步控制 React 中的数据处理。
查看官方文档《》(中文) 和 《》以了解更多本章节中介绍的内容。
State(状态)
现在,我们将 character
数据以数组的形式存储在变量中,并将其作为 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
。 要更新 state(状态) ,我们将使用 this.setState()
,这是操作 state(状态) 的内置方法。 我们将根据我们传递的索引 ,并返回新数组。
注意:您必须使用
this.setState()
来修改数组。 简单地将一个新值应用于this.state.property
将不起作用。
removeCharacter = index => { const { characters } = this.state; this.setState({ characters: characters.filter((character, i) => { return i !== index; }) }); }
filter
不会改变原来的数组,而是创建一个新数组,并且是在 JavaScript 中修改数组的首选方法。 这个特殊的方法是测试索引与数组中的所有索引,并返回除了传递的索引之外的所有索引元素。
现在我们必须将该函数传递给组件,并在每个可以调用该函数的人物项旁边呈现一个按钮。 我们将 removeCharacter
函数作为 prop(属性) 传递给 Table
。
return ( <div className="container"> <Table characterData={characters} removeCharacter={this.removeCharacter} /> </div> );
由于我们将它从 Table
传递给 TableBody
,我们将不得不再次将其作为 prop(属性) 传递,就像我们对 character(人物) 数据所做的那样。
class Table extends Component { render() { const { characterData, removeCharacter } = this.props; return ( <table> <TableHeader /> <TableBody characterData={characterData} removeCharacter={removeCharacter} /> </table> ); } }
这是我们在 removeCharacter()
方法中定义的索引的位置。在 TableBody
组件中,我们将 key/index(键/索引) 作为参数传递,因此 filter
函数知道要删除的是哪一项。 我们将创建一个带有 onClick
的按钮并将其传递给它。
<tr key={index}> <td>{row.name}</td> <td>{row.job}</td> <td><button onClick={() => props.removeCharacter(index)}>Delete</button></td> </tr>
onClick
函数必须通过一个返回removeCharacter()
方法的函数,否则它将尝试自动运行。
真棒。现在我们已经有了删除按钮,我们可以通过删除一个 character(人物) 来修改我们的 state(状态) 。
我删除了 Mac 。
现在您应该了解 state(状态) 是如何初始化的,以及如何修改 state(状态) 。
提交表格数据
现在我们将数据存储在 state(状态) 中,我们可以从 state(状态) 中删除任何数据项。 但是,如果我们希望能够向 state(状态) 添加新数据呢? 在现实的应用程序中,您更可能从空 state(状态) 开始,并将数据添加到 state(状态) 中,例如使用待办事项列表( to-do list) 或购物车。
在接下来我们要做的任何事情之前,让我们从 state.characters
中删除所有硬编码数据,因为我们接下来将通过表单更新 state(状态) 中的数据。
class App extends Component { state = { characters: [] };
现在让我们继续,我们首先创建一个名为 Form.js
的新文件,在其中创建一个 Form
组件。 我们将创建一个类组件,并且我们将使用constructor()
,这是我们到目前为止尚未接触到的。 我们需要 constructor()
来使用它,并接收父级的 props
(属性) 。
我们将把 Form
的初始 state(状态) 设置为具有一些空属性的对象,并将该初始 state(状态) 分配给 this.state
。
import React, { Component } from 'react'; class Form extends Component { constructor(props) { super(props); this.initialState = { name: '', job: '' }; this.state = this.initialState; } }
我们对此表单的目标是每次在表单中更改字段时更新 Form
的 state(状态) ,并且当我们提交时,所有数据将传递到 App
的 state(状态) 中,然后将更新 Table
组件。
首先,我们将创建每次输入更改时运行的函数。 event
将被传递,我们将 Form
的 state(状态) 设置为输入的 name
(键)和 value
。
handleChange = event => { const {name, value} = event.target; this.setState({ [name] : value }); }
在我们继续提交表单之前,让我们先完成这个工作。在 render()
方法中,让我们从 state(状态) 中获取两个属性,并将它们指定为对应于适当形式键的值。我们将运行 handleChange()
方法作为 input 的 onChange
,最后 export(导出) Form
组件。
render() { const { name, job } = this.state; return ( <form> <label>Name</label> <input type="text" name="name" value={name} onChange={this.handleChange} /> <label>Job</label> <input type="text" name="job" value={job} onChange={this.handleChange}/> </form> ); } export default Form;
在 App.js
中,我们可以在表格下方渲染表单。
return ( <div className="container"> <Table characterData={characters} removeCharacter={this.removeCharacter} /> <Form /> </div> );
现在,如果我们回到浏览器,我们会看到一个尚未提交的表单。更新一些字段,您将看到 Form
的本地 state(状态) 正在更新。
最后一步是允许我们实际提交该数据并更新父状态。 我们将在 App
上创建一个名为 handleSubmit()
的函数,该函数将使用现有的this.state.characters
并使用 添加新的 character
参数来更新 state(状态) 。
handleSubmit = character => { this.setState({characters: [...this.state.characters, character]}); }
让我们确保我们把它作为一个参数传递给 Form
。
<Form handleSubmit={this.handleSubmit} />
现在在 Form
中,我们将创建一个名为 submitForm()
的方法,该方法将调用 handleSubmit
函数,并将 Form
的 state(状态) 作为我们之前定义的 character
参数传递。它还会将 state(状态) 重置为初始 state(状态) ,以便在提交后清除表单。
submitForm = () => { this.props.handleSubmit(this.state); this.setState(this.initialState); }
最后,我们将添加一个提交按钮来提交表单。我们使用 onClick
而不是 onSubmit
,因为我们没有使用标准提交(submit)功能。点击将调用我们刚刚创建的 submitForm
方法。
<input type="button" value="Submit" onClick={this.submitForm} />
就是这样! 该应用程序已完成。 我们可以在表格中创建,添加和删除用户。 由于 Table
和 TableBody
已经从 state(状态) 获取数据,它将正确显示。
更多关于 state(状态) 的信息请阅读 React 中文文档中的《》
如果您在学习过程中有点迷茫或者混乱,可以在 。
引入API数据
React 应用开发过程中一个非常常见的用法是从 API 中获取数据。如果您不熟悉 API 是什么或者如何连接到 API ,我建议您阅读,它将引导您了解 API 以及如何将它们与原生的 JavaScript 一起使用。
作为一个小测试,我们可以创建一个 Api.js
文件,并在那里创建一个新的App
。我们可以测试的公共 API 是 ,我在这里有一个 用于 random(随机)*搜索。您可以转到该链接查看 API ,并确保在浏览器上安装了 。
我们将使用 从该 URL 终端收集数据并显示它。您可以通过更改 index.js
中的URL,来切换我们创建的应用程序和此测试文件 – import App from './Api';
。
我不会逐行解释这个代码,因为我们已经学会了创建组件,渲染和映射 state(状态) 数组。此代码的新方面是 componentDidMount()
,一个 React 生命周期方法。Lifecycle(生命周期) 是 React 中调用方法的顺序。Mounting(装载) 到DOM中的项。
当我们引入API数据时,我们希望使用 componentDidMount
,因为我们希望在引入数据之前确保组件已渲染到了 DOM 中。在下面的代码片段中,您将看到我们如何从Wikipedia API引入数据,并将其显示在页面上
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
这将为你创建一个应用程序的 build
文件夹。 将该文件夹的内容放到任何地方,就没你什么事情了,轻松搞定!
我们还可以更进一步,让 npm 为我们部署。我们将构建到 GitHub 页面,因此您必须 并在GitHub上安装代码。
确保您已退出本地 React 环境,因此代码当前未运行。 首先,我们将向 package.json 添加一个homepage
字段,该字段包含我们希望我们的应用程序存在的URL。
"homepage": "https://taniarascia.github.io/react-tutorial",
我们还将这两行添加到 scripts
属性中。
"scripts": { // ... "predeploy": "npm run build", "deploy": "gh-pages -d build" }
在您的项目中,您将向devDependencies添加 gh-pages
。
npm install --save-dev gh-pages
我们将创建 build
,它将包含所有已编译的静态文件。
npm run build
最后,我们将部署到 gh-pages
。
npm run deploy
到这里我们的教程就结束了!该应用程序现已在 上发布。
总结
本文为你介绍 React 的基本概念,包括函数式和类组件、state(状态)、props(属性)、处理表单数据,从一个 API 中获取,构建及部署一个应用程序。 React还有很多东西要学习和做,但我希望你现在能够自信地钻研 React。
- 项目源代码:
- 示例浏览:
如果有任何不清楚的地方,或者您希望在本文或后续文章中看到其他任何内容,欢迎留言告知我们。
推荐资源及文章
- React 教程:2018年学习 React.js 的综合指南
- React 教程:如何使用 webpack 4 和 Babel 构建 React 应用(2018)
- React 组件模式 及 React 组件模式-有状态组件 x 无状态组件、容器组件 x 展示组件、高阶组件 x 渲染回调(函数作为子组件)
- React 教程:函数作为子组件(Function as Child Components),即 渲染回调(Render Callback)
- React 教程:深入理解 React 高阶组件(Higher Order Component,简称:HOC)
英文原文:
state状态:在组件App添加state对象,把之前render里面的数组移到里面, 那render里面的数组不保留的话? 下面return报错:characters未找到? 这里没看明白
class App extends Component {
state = {
characters: []
};
上述问题忽略,找到问题了,在render方法return里面需求这样写: characterData={this.state.characters}