You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Api.jsimportReact,{Component}from'react'classAppextendsComponent{state={data: [],}// Code is invoked after the component is mounted/inserted into the DOM tree.componentDidMount(){consturl='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.stateconstresult=data.map((entry,index)=>{return<likey={index}>{entry}</li>})return<ul>{result}</ul>}}exportdefaultApp
当我刚开始学习
JavaScript
的时候,我就听说了React
,但我承认看了它一眼,它吓到我了。我看到了看起来一堆HTML
和CSS
的混合思想,这不是我们一直努力避免的事情吗?React有什么了不起的?相反,我只专注于学习原始的
JavaScript
,并在需要的时候使用jQuery
。经过几次失败的React
入门尝试之后,我终于开始了解它了,我开始明白为什么我可能想使用React
而不是原始的JS
或jQuery
。我试图将自己学到的内容浓缩成一个很好的介绍,以便与你分享,下面就是~
预备知识
在开始学习
React
之前,你应该事先了解一些事情。例如,如果你之前从没接触过JavaScript
或者DOM
,那么在解决React
之前,你要更加熟悉它们。下面是我认为学习
React
的预备知识:目标
React
概念和相关术语,例如Babel
,Webpack
,JSX
,组件,属性,状态和生命周期React
应用程序,以演示上面的概念。下面是最终的相关源代码和示例。
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
标签,你自定义的代码将存在于该标签中。在编写本文的时,我加载的库是稳定版本的。
React
顶级API
DOM
的方法JavaScript
编辑器,使我们可以在旧的浏览器中使用ES6+
我们应用程序的入口点是
root div
元素,该元素按惯例命名。你还会注意到text / babel
的脚本类型,这是使用Babel
所必需的。现在,让我们编写
React
的第一个模块代码。我们将使用ES6
类来创建一个名为App
的React
组件。现在,我们将添加
render()
方法,这是类组件中唯一需要的方法,用于渲染DOM
节点。在
return
内部,我们将编写简单的看起来像HTML
元素的内容。请注意,我们不在此处返回字符串,因此请勿在元素周围使用引号。这称为JSX
,我们将很快对其进行详细了解。最后,我们将使用
React DOM
的render()
方法将我们创建的App
类渲染到HTML
的root
容器div
中。下面是
index.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
。安装完成之后,移至新创建的目录并启动项目。
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
文件。让我们再次创建我们的
App
组件。以前,我们只有一个<h1>
,但是现在我还要添加一个带有类的div
元素。你会注意到,我们使用的是className
而不是class
。这是我们的第一个提示,此处编写的代码是JavaScript
,而不是HTML
。最后,我们像之前一样渲染
App
到根节点中。下面是完整的
index.js
代码。这次,我们将Component
加载为React
的属性,因此我们不再需要扩展React.Component
。如果你回到
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
赋值给变量的样子。编写
React
并非必须使用JSX
。它在后台运行createElement
,它使用标签,包含属性的对象和子组件并呈现相同的信息。下面的代码具有和上面使用JSX
语法相同的输出。JSX
实际上更接近JavaScript
,而不是HTML
,因此在编写时需要注意一些关键区别。class
被作为JavaScript
中的保留关键字,className
用来替代class
添加CSS
类。JSX
中的属性和方法是驼峰式的 -onclick
将变为onClick
<img />
JavaScript
表达式也可以使用大括号将包括变量,函数和属性的内容嵌入JSX
中。JSX
比原始的JavaScript
中创建和添加许多元素更容易编写和理解,这也是人们如此热爱React
的原因之一。组件
到目前为止,我们创建了一个组件 -
App
组件。React
中几乎所有内容都由组件组成,这些组件可以是类组件或简单组件。大多数
React
应用程序都是许多小组件,所有内容都加载到主要的App
组件中。组件也经常有自己的文件,因此让我们更改项目。移除
index.js
中的App
类,它现在长这样:我们将创建一个名为
App.js
的新文件,然后将组件放在那里。我们将组件导出为
App
并将其加载到index.js
中。将组件分成文件不是强制性的,但是如果不这样做的话,应用程序将变得笨拙和混乱。类组件
让我们创建另一个组件。我们将创建一个表格。创建一个
Table.js
,并用以下数据填充它。我们创建的该组件是一个自定义类组件。我们大写自定义组件,以区别于常规
HTML
元素。回到App.js
中,我们可以首先将Table
导入到其中:然后通过将其加载到
App
的render()
中,然后获得Hello, React!
。我还更改了外部容器的类。如果你重新查看实际环境,则会看到
Table
已加载。现在,我们了解了什么是自定义类组件。我们可以反复使用此组件。但是,由于将数据硬编程(即写死)在其中,因此目前它并不太实用。
简单组件
React
中另外一种类型的组件就是简单组件,它是一个函数。该组件不使用class
关键字。让我们来看下Table
,我们将其拆分为两个简单的组件 - 表头和表体。我们将使用
ES6
箭头函数功能来创建这些简单的组件。首先是表头。然后是表体:
现在,我们
Table
文件如下所示。请注意,TableHeader
和TableBody
组件都在同一个文件中,并且由Table
类组件使用。之后,一切都像之前那样展示。如你所见,组件可以嵌套在其他组件中,并且简单组件和类组件可以混合使用。
作为总结,让我们来比较一个简单组件和一个类组件。
请注意,如果
return
的内容包含在一行中,则不需要括号。Props属性
现在,我们有了一个很棒的
Table
组件,但是数据正在被硬编码。关于React
的重要问题之一是如何处理数据,是通过属性(称为props)和状态(state)来处理数据。现在,我们将专注于使用props
来处理数据。首先,我们将
TableBody
组件的数据移除。然后,将所有数据移到对象数组中,就像我们引入基于
JSON
的API
一样。我们必须在render()
内部创建此数组。现在,我们将通过属性将数据传递给子组件(
Table
),这类似于使用数据data-
属性传递数据的方式。只要不是保留关键字,我们都可以随意调用该属性,因此我将使用characterData
。我传递的数据是Characters
变量,由于它是JavaScript
表达式,因此用大括号括起来。现在,数据已经传递给
Table
,我们要做得是在另一边接收数据。如果你打开
React DevTools
,然后观测Table
组件,你将看到一个数组数据在其属性上。此处存储的数据称为虚拟DOM,这是一种将数据与实际DOM
同步快速有效的方法。但是,此数据尚未在实际的
DOM
中。在表格中,我们可以通过this.props
访问所有属性。我们仅传递一个属性characterData
,因此我们将使用this.props.characterData
来检索该数据。我将使用
ES6
属性的简写来创建一个包含this.props.characterData
的变量。因为,我们的
Table
组件实际上由两个小的简单组件组成,因此我将再次通过props
将其传递给TableBody
。现在,
TableBody
不带任何参数并返回单个标签。我们将把
props
作为参数传递,并通过map返回数组中每个对象的表行。该映射(map)将包含在rows
变量中,我们将其作为表达式返回。如果你查看应用程序的前端,则所有的数据正在加载中。
你会注意到我已经向每个表行添加了一个键索引。在
React
中创建列表时,应始终使用key(键),因为它们有助于识别每个列表项。我们还将在需要操纵列表项的时刻看到这是必要的。Props
是将现有数据传递到React
组件的有效方法,但是该组件无法更改属性 - 它们是只读的。在下一节中,我们将学习如何使用state
来进一步控制React
中的数据处理。state状态
现在,我们将字符数据存在变量的数组中,并将其作为
props
传递。这是一个很好的开始,但是请想象下,如果我们希望能够从数组中删除一个项目。使用props
,我们有了一种单向数据流;但是有了状态state
,我们可以更新组件中的私有数据。你可以将状态
state
视为无需保存或修改,而不必添加到数据库中的任何数据 - 例如,在确认购买之前,在购物车中添加和删除商品。首先,我们将创建一个状态
state
对象。该对象将包含你需要在状态中存储的所有内容属性。对我们来说,就是
characters
。将我们之前创建的对象的整个数组移到
state.characters
中。我们的数据已正式包含在
state
中。由于我们希望能够从表格中删除字符,因此我们将父App
类上创建removeCharacter
方法。要检索状态,我们将使用与以前相同的
ES6
方法获取this.state.characters
。要更新这个状态,我们使用this.setState()
,这是一种用于处理状态state
的内置方法。我们将根据传递的索引index
过滤filter数组,然后返回新数组。filter
不会突变,而是创建一个新数组,并且是在JavaScript
中修改数组的首选方法。这种特殊的方法是测试索引与数组中的所有索引,并返回除传递的索引之外的所有索引。现在,我们必须将该函数传递给组件,并在每个可以调用该函数的字符旁边绘制一个按钮。我们将
removeCharacter
函数作为Table
的属性。由于我们将其从
Table
传递到TableBody
,因此我们将不得不像props
一样再次将其作为属性传递。另外,由于事实证明,在我们的项目中仅由其自己的状态的组件是
App
和Form
,因此最佳实际是将Table
从当前的类组件转换为简单的组件。这就是我们在
removeCharacter()
方法中定义的索引的输入位置。在TableBody
组件中,我们将key/index
作为参数传递,因此过滤器函数知道要删除项目。我们将创建一个带有onClick
的按钮并将其传递。太棒了,现在我们有了删除按钮,我们可以通过删除字符来修改状态。
我删除了
Mac
数据。现在,你应该了解如何初始化状态以及如何修改状态了。
提交表单数据
现在,我们已经将数据存储在状态中,并且可以从状态中删除任何项目。但是,如果我们希望能够添加新数据来到状态呢?在现实世界的应用程序中,你更有可能从空状态开始添加,例如代办事项列表或购物车。
开始前,我们从
state.characters
中删除所有的硬编码的数据,因此我们现在将通过表单进行更新。现在,让我们继续在一个名为
Form.js
的新文件中创建一个Form
组件。我们将创建一个类组件,并在其中使用一个constructor()
,到目前为止,我们还没做过。我们需要constructor()
来使用它,并接收父项的props
。我们将把
Form
的初始状态设置为具有一些空属性的对象,并将该初始状态分配给this.state
。我们对此表单的目标是,每次在表单中更改字段时都会更新
Form
的状态,并且在我们提交时,所有这些数据将传递到App
状态,然后App
状态将更新Table
。首先,我们将使该函数在每次对输入进行更改时都将运行。
event
将传递,我们将设置Form
的状态为输入name
(键)和value
(值)。在继续提交表单之前,我们需要这个运行起来。在渲染中,让我们从
state
中获取两个属性,并将它们分配为正确的表单键对应的值。我们将把handleChange()
作为输入的onChange
运行,最后导出Form
组件。在
App.js
中,我们可以在下表中渲染表单。现在,如果我们转到应用程序的前端,将会看到尚未提交的表单。更新一些字段,你将看到正在更新的
Form
的本地状态。太棒了。最后一步是允许我们实际提交该数据并更新父状态。我们将在
App
上创建一个名为handleSubmit()
的函数,该函数通过使用ES6扩展运算符获取现有的this.state.characters
并添加新的character
参数来更新状态。确保我们将其作为
Form
上的参数传递。现在,在
Form
中,我们将创建一个称为SubmitForm()
的方法,该方法将调用该函数,并将Form
状态作为我们先前定义的character
参数传递。还将状态重置为初始化状态,以便在提交后清除表单。最后,我们将添加一个提交按钮以提交表单。因为我们没有使用标准的提交功能,我们我们使用的是
onClick
而不是onSubmit
。点击将调用我们刚才创建的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
引入数据,并将其显示在页面上。一旦你在本地服务器中保存并运行此文件后,你将看到
DOM
中显示的Wikipedia API
数据。还有其他生命周期的方法,但是这里将不再讨论它们。你可以在此处于阅读有关React组件的更多信息。
*维基百科搜索选项可能不是随机的。 这可能是我在2005年率先发表的文章。
构建和发布一个React应用
到目前为止,我们所做的一切都在开发环境中。我们一直在进行即时的编译,热重载和更新。对于生产环境,我们将要加载静态文件 - 没有源代码。我们可以通过构建并部署它来做到这一点。
现在,如果你只想编译所有
React
代码并将其放置在某个目录的根目录中,则只需运行以下代码:这将
build
一个包含你的应用程序的构建文件夹。将文件夹放在你想要的位置就可以了。我们可以更进一步,让
npm
为我们部署。我们将构建Github pages
,因此你必须熟悉Git并在Github
上获取代码。确保你已经退出本地
React
环境,因此该代码未在当前运行。首先,我们要在package.json
中添加一个homepage
字段,其中包含我们希望应用程序继续存在的URL
。我们也需要将下面的两行代码添加到
scripts
的属性中。在你的项目中,将
gh-pages
添加到devDependencies
我们将创建
build
,其中将包含所有已编译的静态文件。最后,我们将部署到
gh-pages
。完成部署后,你可以通过https://taniarascia.github.io/react-tutorial 查看。
总结
本文很好地向你介绍了
React
,简单组件和类组件,状态,属性,使用表单数据,从API
提取数据以及部署应用程序。使用React
还有更多的东西要学习和实践,但是我希望你现在有足够的信心钻研React
并学下去。参考&后话
The text was updated successfully, but these errors were encountered: