React 初学者完整指南:Hooks 版
几年前,我根据自己教过的一个研讨会写了一篇React 入门教程。从那时起,我已经教过数百名新的 Web 开发者学习 React,这个库也得到了显著的发展。我觉得是时候回归基础,讨论如何在 Hooks 时代从零开始学习 React 了。
本博客文章教程的一些先决条件:HTML、CSS 和 JavaScript 基础知识。
React 是一个 JavaScript 库,由 Facebook 于 2013 年开发。它加速并简化了前端开发流程。它拥有许多有助于用户界面开发的关键功能,例如 JSX、组件和虚拟 DOM。在当今的前端开发时代,它几乎不可或缺。在本教程中,我们将学习 React 基础知识,使用 Create React App 搭建项目,使用 React 状态和属性构建应用程序,然后将其部署到 AWS Amplify。
成分
你可能在编程生涯的早期就学会了“分离关注点”,即将 HTML、CSS 和 JS 放在不同的文件中。React 则完全颠覆了这一点。我们将网页拆分成多个称为“组件”的块,并将它们的所有显示和逻辑代码都写在一个文件中。这将提高用户界面的模块化程度,让我们可以以无限的组合方式组合组件并反复使用它们。
在许多网页中,类似的用户界面组件会反复出现——例如 Facebook 的“点赞”按钮。它出现在帖子、视频和图片上。如果使用标准 HTML,则每个按钮都需要单独编写,并为其添加一个类来设置样式,然后还需要编写 JavaScript 代码来实现它们的行为。如果需要更新这些按钮,则可能需要在很多地方修改代码。
React 基于组件的架构允许我们反复重复使用该按钮,并且仅在需要时在一个地方更新代码。
让我们看看如何将 Facebook 状态分解为几个部分:
我们还可以拥有子组件,即父组件内的组件。
例如,状态底部的三个按钮可以分解为它们自己的组件。
根据应用程序的需求,您可以通过多种方式分解这些组件和子组件。
安装和设置
首先,安装Node.js。如果你还没有接触过 Node.js,它是一个允许你在浏览器之外编写 JavaScript 的运行时。在本例中,我们将使用它来尽可能简化 React 应用程序的开发。
安装 Node 后,打开命令行并运行:npx create-react-app color-switcher
。注意,此命令可能需要几分钟才能运行。
npx
是 Node 附带的工具,允许您无需先安装命令即可运行命令。- 我们用它来运行,
create-react-app
正如其名称所暗示的那样!它为我们搭建了一个 React 应用程序,并设置了 Babel 和 Webpack,这两个非常重要的工具我们将在本教程的后面部分继续讨论。 - 最后
color-switcher
是我们应用程序的名称,您需要npx create-react-app your-app-name
为您构建的每个应用程序重新运行该命令。
一旦您的应用程序创建到为我们创建的cd
目录中。create-react-app
cd color-switcher
创建 React App 生成的文件
在您选择的文本编辑器中打开目录,然后检查已创建的文件。
有很多!不过别害怕,让我们快速浏览一下create-react-app
生成的文件。突出显示的文件对我们来说很重要:
- node_modules/——我们在项目中使用的 Node 模块,本质上是其他人的代码,可以让我们的生活更轻松。
- 民众/
- favicon.ico - 当您收藏某个网站时显示的图标
- index.html - JavaScript 附加到的文件
- logo.png 文件 - 我们应用程序的不同图标
- manifest.json - 允许我们将我们的应用程序变成渐进式 Web 应用程序,我们今天不会将我们的应用程序变成这样的。
- robots.txt - 声明我们网站上的机器人规则
- 源码/
- App.css - App 组件的样式将放在这里
- App.js - 我们的 App 组件将在此处编写
- App.test.js - 您可以在其中为 App 组件编写自动化测试的文件
- index.css - 应用程序的全局样式文件
- index.js - React 应用程序的配置
- logo.svg - React 徽标
- serviceWorker.js - 要配置的代码
- setupTests.js - 自动化测试配置
- .gitignore - 你想保留在本地并对 git 隐藏的文件
- package.json - 保存项目元数据
- package-lock.json - 自动生成的文件,用于跟踪依赖项
创建了一堆文件,但我们只需要担心其中的几个。
index.js 文件
让我们分析一下第一个部分的内容index.js
:
import React from 'react'
-导入React 库。每个使用 JSX 语法的文件中都需要它。- import ReactDOM from 'react-dom'
ReactDOM 允许我们在浏览器中使用 React import './index.css'
- 应用全局样式import App from './App'
- 导入App
组件
现在来看看重要的代码!我们将把<App>
组件附加到一个带有 id 的元素上#root
。你可以在文件中找到该元素public/index.html
。这样我们的 React 代码才能真正渲染到页面上。
React 使用虚拟 DOM,它是您在原生 JavaScript 或 JQuery 中通常交互的 DOM 的虚拟表示。它reactDOM.render
会将虚拟 DOM 渲染为实际的 DOM。在后台,当界面上需要更改某些内容时,React 会执行大量工作来高效地编辑和重新渲染 DOM。
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
该<React.StrictMode>
组件是一个工具,它可以为您提供有关代码中可能存在的问题的额外警告。
再次,我们将忽略服务工作者代码,它超出了我们需要做的事情。
您不需要更改index.js
文件中的任何内容,我只是想运行它,因为它对于使我们的应用程序运行至关重要。
React Hello World
现在到了最有趣的部分,编写代码!打开你的App.js
文件。这将是我们应用程序的顶级组件,或者说根组件。
在这个文件中,我们已经写了一些代码。我们再次导入 React(每个使用 React 的文件中都需要这样做)、React Logo 以及此 App 组件特有的 CSS 文件。
我们还有一个函数,App
它返回一堆看起来像 HTML 的内容——这实际上是 JSX。
最后,我们导出组件,以便将其导入到其他文件中,在本例中,是为我们生成的 index.js。
让我们继续删除徽标导入并更改 JSX 代码,以便它仅返回<h1>Hello, World</h1>
import React from 'react'
- import logo from './logo.svg'
import './App.css'
function App () {
return (
+ <h1>Hello world!</h1>
)
}
export default App
JSX 是 JavaScript 的一个扩展,它允许你直接在 JavaScript 代码中编写类似 HTML 的代码。你无法在浏览器中原生使用 JSX,但我们将使用一个名为 Babel 的库将 JSX 转译(或转换)为常规 JavaScript,以便浏览器能够理解。JSX 在 React 中实际上是可选的,但你会看到它在绝大多数情况下被使用。
好的,现在你已经编写了你的第一个 React 代码,但是如何查看输出呢?返回你的 CLI 并运行npm run start
。一个显示你的 React 应用的网页应该会弹出。它会进行热加载,因此每次你更改代码并保存更改后,你的应用程序都会自动显示这些更改。要退出服务器,你可以按ctrl
+ c
。在开发 React 应用时,打开两个终端窗口或选项卡可能会很有帮助,因为你无法在服务器运行的会话中编写其他命令。
反应颜色切换器
首先,我们将构建一个颜色选择器应用程序——页面的背景将根据用户选择的按钮改变颜色。
第一步是构建静态用户界面。首先,我们将添加一个封闭元素div
,作为 React 应用程序的顶级元素。然后,我们将div
在其中添加另一个元素,使内容在页面上居中。我们还将添加一个页眉作为页面标题,以及三个按钮。我们还将className
为元素添加一些属性。在 JavaScript 中,aclass
用于在面向对象编程中创建类,因此,React 不能使用这个词class
来为元素组添加样式的类名。因此,它使用className
。
classNames
我们将向元素中添加以下内容:
import React from 'react'
import './App.css'
function App () {
return (
<div className='react-root'>
<div className='centered'>
<h1>Color Picker</h1>
<button className='red'>red</button>
<button className='blue'>blue</button>
<button className='yellow'>yellow</button>
</div>
</div>
)
}
export default App
由于本教程重点介绍 React,我们只需将一些 CSS 代码复制到您的 中App.css
。删除其中的内容并将其替换为:
html, body, #root, .react-root {
height: 100%;
width: 100%;
background-color: white;
color: black;
display: flex;
justify-content: center;
align-items: center;
}
.centered {
text-align: center;
}
button {
padding: 10px;
margin: 5px;
border: 2px solid white;
color: white;
font-size: 20px;
}
.red {
background-color: red;
color: white;
}
.blue {
background-color: blue;
color: white;
}
.yellow {
background-color: yellow;
color: black;
}
现在,你的应用程序应该如下所示:
现在我们需要真正让它做点什么!
我们希望在应用运行时更改的任何变量都需要存储在状态中。这将导致 React 在每次状态变量更新时自动更新组件的外观。
反应状态
为了利用状态,我们将从useState
React 导入钩子。
Hooks 对 React 来说是新事物——它是在 2018 年底推出的。React 与我五年前学习它时相比已经大不相同了。当时 ES6 尚未完全实现,所以我们使用对象和React.createClass
函数来编写组件。之后是 JavaScript 类的时代,最近,React 实现了 Hooks,它允许我们只使用函数来编写组件。这使得 React 的语法更简洁,更简洁。根据React 文档,“Hooks 是一种函数,它允许我们‘钩住’ React 的功能。”
在我们的 App.js 组件中,我们将更新第一行代码。
+ import React, { useState } from 'react'
import './App.css'
这个useState
钩子接受一个参数:state 的初始值。然后,它会返回一个数组,其中包含两个值。第一个是 state 变量的值,第二个是用于更新 state 的函数。我们将使用数组解构将返回的两个值分别赋值给它们自己的变量。
import React, { useState } from 'react'
import './App.css'
function App () {
+ const [color, setColor] = useState('')
return (
<div className='react-root'>
<div className='centered'>
<h1>Color Picker</h1>
<button className='red'>red</button>
<button className='blue'>blue</button>
<button className='yellow'>yellow</button>
</div>
</div>
)
}
export default App
如果你在控制台中打印每一项,你会看到color
一个空字符串,因为我们为 useState 提供了参数 ''。如果你把这个空字符串改成 'blue',那么 color 变量的值就会是 blue! 。setColor
这是一个函数,我们将用它来更新 color 变量。
现在,我们需要添加一个事件监听器,以便当用户点击我们的按钮时,状态中存储的颜色会更新。
color
首先,我们将在界面上显示当前的值。我们可以通过将颜色变量写在花括号中来实现,这告诉 React 花括号内的任何代码都是 JavaScript 代码。
我们还将为第一个按钮添加 onClick 属性,然后onClick
添加一个在事件触发时运行的函数。这就是我们在 React 中编写事件监听器的方法。目前,我们只需console.log('clicked')
……
import React, { useState } from 'react'
import './App.css'
function App () {
const [color, setColor] = useState('')
return (
<div className='react-root'>
<div className='centered'>
<h1>Color Picker</h1>
+ {color}
+ <button className='red' onClick={() => console.log('clicked')}>
red
</button>
<button className='blue'>blue</button>
<button className='yellow'>yellow</button>
</div>
</div>
)
}
export default App
检查你的 JavaScript 控制台并看看发生了什么!
现在,我们将修改事件监听函数,使其改为更改颜色状态变量。我们可以通过使用之前提供的setColor
函数来实现useState
。
<button className='red' onClick={() => setColor('red')}>
red
</button>
现在,您可以看到,当您点击按钮时,页面上会显示“红色”字样!现在,让我们让其他两个按钮也能正常工作。
<button className='blue' onClick={() => setColor('blue')}>blue</button>
<button className='yellow' onClick={() => setColor('yellow')}>yellow</button>
我们最后要做的就是实际更改页面的颜色,而不仅仅是在页面上显示颜色名称。在我们的 CSS 文件中,我们已经为颜色添加了三个类——黄色、红色和蓝色。我们需要做的是将这些类添加到我们的react-root
元素上,以便它能够根据color
变量改变颜色。我们需要让 className 接受 JavaScript 代码而不是字符串,然后我们将使用字符串插值将我们的color
类添加到元素中。
<div className={`react-root ${color}`}>
我们的最终代码应该是这样的:
import React, { useState } from 'react'
import './App.css'
function App () {
const [color, setColor] = useState('')
return (
<div className={`react-root ${color}`}>
<div className='centered'>
<h1>Color Picker</h1>
<button className='red' onClick={() => setColor('red')}>red</button>
<button className='blue' onClick={() => setColor('blue')}>blue</button>
<button className='yellow' onClick={() => setColor('yellow')}>yellow</button>
</div>
</div>
)
}
export default App
React Props
现在我们已经使用了 React 的一些最重要的特性:JSX 和 state。接下来我想向你展示另外两个:components 和 props。
目前我们实际上正在使用一个组件:App
。但是,我们希望组件小巧且可复用。目前,我们的按钮遵循一种模式。每个按钮都显示文本,具有一个 className 和一个 onClick 事件。我们将创建第二个ColorChangeButton
组件,以便尽可能多地复用代码,并且如果将来需要更新按钮,也可以更轻松地进行操作。
第一步是在您的src/
文件夹中创建另一个名为 的文件ColorChangeButton.js
。
现在,我们将在此文件中创建第二个 React 组件。
// ColorChangeButton.js
import React from 'react'
function ColorChangeButton () {
return (
<button>Hi!</button>
)
}
export default ColorChangeButton
我们现在回到我们的 App.js 并导入ColorChangeButton
:
// App.js
import React, { useState } from 'react'
import './App.css'
+ import ColorChangeButton from './ColorChangeButton'
在我们的 JSX 代码中,我们将创建三个实例ColorChangeButton
。
// App.js
return (
<div className={`react-root ${color}`}>
<div className='centered'>
<h1>Color Picker</h1>
+ <ColorChangeButton />
+ <ColorChangeButton />
+ <ColorChangeButton />
<button className='red' onClick={() => setColor('red')}>red</button>
<button className='blue' onClick={() => setColor('blue')}>blue</button>
<button className='yellow' onClick={() => setColor('yellow')}>yellow</button>
</div>
</div>
)
轰!现在页面上应该又出现了三个按钮,都显示着Hi!
。这就是我们在 React 中创建并引入第二个组件的方法。
但是,目前我们的组件相当枯燥。它们都说着同样的事情。我们希望这些组件最终能够取代我们之前编写的三个变色按钮,所以我们需要允许按钮显示不同的颜色和不同的文本。
React 使用单向数据流,这意味着我们只能将数据从父组件传递到子组件。我们将使用单向props
数据流将数据从一个组件传递到另一个组件。
// App.js
return (
<div className={`react-root ${color}`}>
<div className='centered'>
<h1>Color Picker</h1>
+ <ColorChangeButton color='red' />
+ <ColorChangeButton color='blue' />
+ <ColorChangeButton color='yellow' />
<button className='red' onClick={() => setColor('red')}>red</button>
<button className='blue' onClick={() => setColor('blue')}>blue</button>
<button className='yellow' onClick={() => setColor('yellow')}>yellow</button>
</div>
</div>
)
在我们的父组件 App 中,我们可以使用类似 HTML 属性的形式来传递 props。在本例中,color 是 prop 的名称,其值位于等号后面,第一个组件为 'red',第二个组件为 'blue',第三个组件为 'yellow'。
现在,我们需要在子组件中使用这些 props。切换到ColorChangeButton.js
。首先,我们将使函数接受参数 props。
// ColorChangeButton.js
function ColorChangeButton (props) {
...
}
然后,你可以console.log
在道具回归之前看看那里有什么:
{ color: 'red' }
{ color: 'blue' }
{ color: 'yellow' }
它是一个对象!React 将我们从父组件发送的每个 prop 组合成一个对象,其中包含子组件中的每个键和值。因此,要在子组件中访问颜色,我们可以这样做props.color
。让我们让按钮将颜色显示为文本,并将颜色作为类添加到按钮,以便显示正确的颜色。
// ColorChangeButton.js
import React from 'react'
function ColorChangeButton (props) {
return (
+ <button className={props.color}>{props.color}</button>
)
}
export default ColorChangeButton
现在我们的按钮看起来就像它们应该的样子了!我们要做的最后一件事是让点击事件起作用。在我们的 App.js 中,我们编写了以下代码来更改当前颜色:
<button className='red' onClick={() => setColor('red')}>red</button>
我们遇到的一个问题是,它setColor
定义在我们的App
组件中,所以我们无法访问它ColorChangeButton
。不过好消息是:我们有一种方法可以将数据从父组件传递到子组件,也就是我们在上一步学到的方法:props!让我们将这个setColor
函数作为 prop 传递给我们的ColorChangeButton
组件。
我还将删除我们原来的三个按钮,因为我们不再需要它们。
// App.js
return (
<div className={`react-root ${color}`}>
<div className='centered'>
<h1>Color Picker</h1>
+ <ColorChangeButton color='red' setColor={setColor} />
+ <ColorChangeButton color='blue' setColor={setColor} />
+ <ColorChangeButton color='yellow' setColor={setColor} />
</div>
</div>
)
现在,如果您返回到ColorChangeButton
console.log 查看 props 是什么,您会看到对象中有第二个项目,例如:
{
color: "red"
setColor: ƒ ()
}
让我们使用 setColor 函数:
function ColorChangeButton(props) {
return (
+ <button className={props.color} onClick={() => props.setColor(props.color)}>
{props.color}
</button>
)
}
export default ColorChangeButton
现在每个按钮都应该按预期工作了!这种将状态更改函数从父组件向下传递到子组件的模式称为反向数据流。它使我们能够规避 React 单向数据流的特性。
部署
请注意,我是 AWS Amplify 团队的开发倡导者,如果您对此有任何反馈或疑问,请联系我或在我们的 discord 上提问 - discord.gg/amplify!
太棒了,我们的应用程序终于完成了。不过还有一个小问题:我们的应用程序只能在本地访问,这意味着我们无法将 localhost URL 发送给朋友让他们查看。我们需要部署我们的应用程序,以便网络上的任何人都可以看到它。我们将使用 AWS Amplify 来完成此操作,只需单击几下即可。
首先,我们需要通过以下方式将本教程代码推送到 GitHub:
- 通过单击页面右上角的加号按钮来创建一个新的存储库。
- 选择存储库名称并单击
create repository
- 然后,复制命令
…or push an existing repository from the command line
并在终端中运行它们。 - 在您的终端中运行
git add . && git commit -m "tutorial complete" && git push
以发送您的最新更改。
然后部署它:
-
如果您还没有AWS 账户,请创建一个。
-
导航至Amplify 控制台
-
单击橙色
connect app
按钮。 -
GitHub
在菜单中选择From your existing code
,然后单击继续
- 输入您刚刚创建的 GitHub 仓库的名称(它应该会自动填充!)然后单击
next
-
构建设置将自动填充,因此您只需
next
单击Configure build settings
-
点击
Save and deploy
。
在您 AWS 账户生效后的前 12 个月,Amplify 提供免费套餐,基本涵盖您的主机托管费用。之后,您可以点击此处了解更多定价信息!
构建您的应用可能需要几分钟时间,但一旦构建完成,您将获得一个任何人都可以访问的 URL!您可以通过此 URL访问我的应用。
后续步骤
本教程带你了解了 React 数据流、组件和项目设置的基础知识。以下是一些很棒的学习资源:
此外,如果您喜欢以直播的方式观看,我还对本教程的内容进行了直播。如果您扩展了构建的内容,请在Twitter 上与我分享!
文章来源:https://dev.to/aws/a-complete-beginner-s-guide-to-react-hooks-edition-1bi0