介绍
在本教程中,您将使用 React 挂钩创建一个倒计时器,以更新 React 组件的状态和管理副作用。
使用 React Hooks,您可以创建更清洁的代码,在组件之间创建可重复使用的逻辑,并在没有类的情况下更新状态。
计时计时器是一个常见的用户界面组件. 它们可以向用户传达他们在做某件事多久或多长时间,直到某个事件发生。
到本教程结束时,您将使用 React 的 useState()
和 useEffect()
锁定功能性和可重复使用的 Countdown 计时器。
前提条件
在您开始本指南之前,您将需要以下内容:
要在 macOS 或 Ubuntu 18.04 上安装此功能,请遵循 如何在 macOS 上安装 Node.js 并创建本地开发环境 的步骤或 如何在 Ubuntu 18.04 上安装 Node.js 使用 PPA 设置项目的 How To Set Up a React Project with Create React App部分] *在本教程中,您将使用 Create React App创建应用程序。
此教程已通过 Node.js v16.13.1, npm
v8.2.0 和 react
v17.0.2 进行验证。
步骤 1 – 创建一个空的项目
在此步骤中,您将使用 Create React App创建一个新项目,然后您将删除在启动项目时安装的样本项目和相关文件。
要开始,创建一个新项目. 在终端中,运行以下脚本以使用create-react-app
安装新项目:
1npx create-react-app react-hooks-timer
项目完成后,更改到目录:
1cd react-hooks-timer
在新的终端卡或窗口中,使用 Create React App start script启动项目。
1npm start
如果项目未在浏览器窗口中打开,您可以使用http://localhost:3000/
打开,如果您正在从远程服务器运行,则地址将是http://your_server_ip:3000
。
您的浏览器将加载由 Create React App 生成的 React 应用程序:
您将构建一组新的自定义组件,因此您需要从清除一些锅炉板代码开始,以便您可以有一个空的项目。
要开始,请在文本编辑器中打开src/App.js
。 这是注入到页面的根组件。 所有组件将从这里开始。 您可以找到有关App.js
的更多信息,请参阅How To Set Up a React Project with Create React App
(如何使用Create React App设置反应项目
(LINK0
))。
使用以下命令打开src/App.js
:
1nano src/App.js
你會看到這樣的檔案:
1[label react-hooks-timer/src/App.js]
2import React from 'react';
3import logo from './logo.svg';
4import './App.css';
5
6function App() {
7 return (
8 <div className="App">
9 <header className="App-header">
10 <img src={logo} className="App-logo" alt="logo" />
11 <p>
12 Edit <code>src/App.js</code> and save to reload.
13 </p>
14 <a
15 className="App-link"
16 href="https://reactjs.org"
17 target="_blank"
18 rel="noopener noreferrer"
19 >
20 Learn React
21 </a>
22 </header>
23 </div>
24 );
25}
26
27export default App;
然后更换返回
声明中的所有内容以返回一组<div>
标签,这样你就可以获得一个有效的页面,不会返回任何内容。
1[label react-hooks-timer/src/App.js]
2import React from 'react';
3import logo from './logo.svg';
4import './App.css';
5
6function App() {
7 return (
8 <div>
9 </div>
10 )
11}
12
13export default App;
然后,删除从
./logo.svg导入标志
的行。
保存和退出文本编辑器。
最后,删除标志,因为你不会在这个应用程序中使用它,这是一个很好的做法去除未使用的文件,当你工作,以避免混淆。
在终端窗口中,输入以下命令:
1rm src/logo.svg
现在项目已经设置,您可以创建您的第一个组件。
步骤二:计算剩余时间
在此步骤中,您将创建一个函数,该函数计算当前日期和 Hacktoberfest 第一天之间剩余的时间。
首先,设置一个名为calculateTimeLeft
的函数:
1[label react-hooks-timer/src/App.js]
2// ...
3
4const calculateTimeLeft = () => {
5
6};
7
8// ...
接下来,在函数中,你会使用JavaScript的日期
对象来找到当前的年份
。
创建一个名为年
的变量,将其设置为JavaScript的日期
方法Date.getFullYear()
。
在calculateTimeLeft
函数中添加以下代码:
1[label react-hooks-timer/src/App.js]
2// ...
3
4const calculateTimeLeft = () => {
5 let year = new Date().getFullYear();
6}
7
8// ...
<$>[注]
**注:**您可以使用JavaScript Date
对象来处理日期和时间。
Date.getFullYear()
方法将捕捉当前的一年。
现在,您可以使用此变量计算当前日期和 Hacktoberfest 的第一天之间的差异。
在 calculateTimeLeft
函数中,添加一个名为 difference
的新变量,用以下代码将其设置为一个新的 Date
对象:
1[label react-hooks-timer/src/App.js]
2// ...
3
4const calculateTimeLeft = () => {
5 let year = new Date().getFullYear();
6
7 const difference = +new Date(`10/01/${year}`) - +new Date();
8}
9
10// ...
新日期
对象前的+
是指JavaScript将对象投放为整数,这为您提供了对象的Unix时刻印,以微秒为代表。
<$>[注] **注:**对于本教程,请确保您正在计算的日期设置为未来,否则您将遇到错误
要保持代码可重复使用,请使用 JavaScript 模板字母并添加年
变量以及 Hacktoberfest 的月份和日期。
现在,你已经计算了数毫秒的总数,直到倒计时器到期,你需要将数毫秒转换为更友好的和人读的东西。
步骤 3 — 格式化为日期、小时、分钟和秒
在此步骤中,您将创建一个名为timeLeft
的空对象,使用if
语句来检查剩余时间,并使用数学和模块(%)运算符计算小时,分钟和秒的总数。
首先,创建一个名为timeLeft
的空白对象,然后在如果
语句中填写天、小时、分钟和秒。
在calculateTimeLeft
函数中添加以下代码:
1[label react-hooks-timer/src/App.js]
2// ...
3
4const calculateTimeLeft = () => {
5 let year = new Date().getFullYear();
6 let difference = +new Date(`10/01/${year}`) - +new Date();
7
8 let timeLeft = {};
9}
10
11// ...
现在创建一个如果
语句,将比较差异
变量,看看它是否大于0
。
将此代码添加到calculateTimeLeft
函数中:
1[label react-hooks-timer/src/App.js]
2// ...
3
4const calculateTimeLeft = () => {
5 let year = new Date().getFullYear();
6 let difference = +new Date(`10/01/${year}`) - +new Date();
7
8 let timeLeft = {};
9
10 if (difference > 0) {
11 timeLeft = {
12 days: Math.floor(difference / (1000 * 60 * 60 * 24)),
13 hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
14 minutes: Math.floor((difference / 1000 / 60) % 60),
15 seconds: Math.floor((difference / 1000) % 60)
16 };
17 }
18}
19
20// ...
在此代码中,你将日期、小时、分钟和秒的数字旋转下来,然后放下剩余数以获得整数值,然后比较差异
,看看它是否大于0
。
最后,您需要返回timeLeft
,以便在组件中的其他地方使用该值。
将此代码添加到calculateTimeLeft
函数中:
1[label react-hooks-timer/src/App.js]
2// ...
3
4const calculateTimeLeft = () => {
5 let year = new Date().getFullYear();
6 let difference = +new Date(`10/01/${year}`) - +new Date();
7
8 let timeLeft = {};
9
10 if (difference > 0) {
11 timeLeft = {
12 days: Math.floor(difference / (1000 * 60 * 60 * 24)),
13 hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
14 minutes: Math.floor((difference / 1000 / 60) % 60),
15 seconds: Math.floor((difference / 1000) % 60)
16 };
17 }
18
19 return timeLeft;
20}
21
22// ...
现在你已经创建了一个函数,计算剩余时间直到Hacktoberfest,你可以添加在应用程序状态,将控制和更新你的计时器。
步骤 4 — 更新您的应用程序状态,使用useState
和useEffect
使用 React Hooks,您可以将状态管理功能添加到现有功能组件中,而不将其转换为类。
在此步骤中,您将从 React 导入useState
和useEffect
的锁定,以管理该组件的状态。
在App.js
文件的顶部,在导入陈述中添加useState
和useEffect
:
1[label react-hooks-timer/src/App.js]
2import React, { useEffect, useState } from "react";
3
4// ...
此代码告诉 React 您想要使用这些特定的夹克及其在 React 中可用的功能。
要使倒计时器工作,您需要将我们先前编码的剩余时间方法线上来更新状态:
在calculateTimeLeft
函数后添加以下代码:
1[label react-hooks-timer/src/App.js]
2// ...
3
4const [timeLeft, setTimeLeft] = useState(calculateTimeLeft());
5
6// ...
这个JavaScript语法被称为 _array destructuring。
useState
方法接受设置初始状态的参数,并返回包含当前状态和设置状态的函数的数组。
「timeLeft」將帶來我們的時間偏差對象,並為我們提供設定狀態的方法. 在組件負載上,「timeLeft」值被設定為目前時間偏差值。
接下来,您将使用useEffect
链接来处理组件的副作用。
<$>[注] 注: _ side effect_ 是指任何影响正在执行函数范围外的东西。
在此解决方案中,您将在useEffect
链接中使用一个setTimeout
方法。
React中的setTimeout
方法等大多数非同步行为都是用useEffect
和useState
链接的组合来定义的。
<$>[注]
**注:**您可以阅读更多关于何时以及如何使用诸如setTimeout
和setInterval
等方法的信息,请参阅React Docs
(https://reactjs.org/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often)。
在useState()
函数后添加以下代码:
1[label react-hooks-timer/src/App.js]
2// ...
3
4const [timeLeft, setTimeLeft] = useState(calculateTimeLeft());
5
6useEffect(() => {
7 const timer = setTimeout(() => {
8 setTimeLeft(calculateTimeLeft());
9 }, 1000);
10});
11
12// ...
useEffect
是更新剩余时间的值。 默认情况下,React 会在每次渲染后重新调用效果。
每当timeLeft
变量在状态中被更新时,useEffect
会启动,每次启动时,我们会设置一个计时器为1秒(或1000ms),该计时器会更新该时间过后剩余的时间。
循环将在之后每秒继续。
为了帮助消除堆积时间和造成错误的潜力,在useEffect
链接中添加clearTimeout
方法。
添加一个clearTimeout
方法,并将变量计时器作为参数输入:
1[label react-hooks-timer/src/App.js]
2// ...
3
4useEffect(() => {
5 const timer = setTimeout(() => {
6 setTimeLeft(calculateTimeLeft());
7 }, 1000);
8
9 return () => clearTimeout(timer);
10});
11
12// ...
返回
函数每次运行useEffect
执行计时器
,除第一次运行组件外,如果组件没有安装,则会清除时间。
现在,你的状态已设置为calculateTimeLeft()
对象,并且正在更新你的效果链,它可以用来构建你的显示组件。
步骤 5 — 使用Object.keys
在此步骤中,您将使用Object.keys
重复timeLeft
对象并构建显示组件,您将使用显示组件显示 Hacktoberfest 开始前剩余的时间。
首先,在useEffect
链接下创建一个名为timerComponents
的新变量:
1[label react-hooks-timer/src/App.js]
2// ...
3
4const timerComponents = [];
5
6// ...
在timeLeft
中重复键后,您将使用此变量来将剩余时间推向一个新的 JSX 组件。
接下来,使用 Object.keys
来重复您从您的 calculateTimeLeft
函数返回的 timeLeft
对象。
在「timerComponents」变量中添加此代码:
1[label react-hooks-timer/src/App.js]
2// ...
3
4const timerComponents = [];
5
6Object.keys(timeLeft).forEach((interval) => {
7 if (!timeLeft[interval]) {
8 return;
9 }
10
11 timerComponents.push(
12 <span>
13 {timeLeft[interval]} {interval}{" "}
14 </span>
15 );
16});
17
18// ...
在这里,代码通过timeLeft
对象的属性循环. 如果计时间隔具有大于零的值,它会将一个元素添加到timerComponents
数组中。
<$>[注]
**注:**代码中的附加 {" "}
被用来使显示剩余时间的间隔在屏幕上显示时不会相互碰撞。
{}
允许您在 JSX 中使用 JavaScript,而 ""
则添加空间
<$>
现在您已经准备好在应用程序组件返回
声明中添加新的 JSX,以显示剩余时间直到 Hacktoberfest。
步骤 6 – 显示剩余时间
在此步骤中,您将添加 JSX 组件到应用程序组件的回报
声明中。
要使用timerComponents
数组,您需要检查其长度,然后返回它,或者让用户知道该计时器已经过期。
在返回
声明中添加此代码:
1[label react-hooks-timer/src/App.js]
2// ...
3
4return (
5 <div>
6 {timerComponents.length ? timerComponents : <span>Time's up!</span>}
7 </div>
8);
9
10// ...
在 React JSX 组件中,您使用三级运算符代替 JavaScript 语句如果
。
「timerComponents.length」代码行检查是否有任何东西在「timerComponents」阵列中,如果有,则返回,否则返回「时间已经到来!」。
接下来,您将添加两个 JSX 组件到回报
声明中,以便用户知道他们正在计算什么:
1[label react-hooks-timer/src/App.js]
2// ...
3
4return (
5 <div>
6 <h1>Hacktoberfest 2020 Countdown</h1>
7 <h2>With React Hooks!</h2>
8 {timerComponents.length ? timerComponents : <span>Time's up!</span>}
9 </div>
10);
11
12// ...
要使用当前年份而不是硬编码2020
,您可以创建一个新的状态变量,并将初始状态设置为新日期().getFullYear();
。
在第一个 useState()
变量之后,添加以下代码:
1[label react-hooks-timer/src/App.js]
2// ...
3
4const [timeLeft, setTimeLeft] = useState(calculateTimeLeft());
5const [year] = useState(new Date().getFullYear());
6
7// ...
此方法将捕捉您在calculateTimeLeft
函数中使用的当前年份。
然后,您可以从您的h1
中删除硬代码2020
并用年
更换:
1[label react-hooks-timer/src/App.js]
2// ...
3
4return (
5 <div>
6 <h1>Hacktoberfest {year} Countdown</h1>
7 <h2>With React Hooks!</h2>
8 {timerComponents.length ? timerComponents : <span>Time's up!</span>}
9 </div>
10);
11
12// ...
这将显示您的状态变量,现在它将始终有当前的一年。
点击此 GitHub 存储库查看完整的代码。
结论
在本教程中,您使用useState
和useEffect
链接构建了倒数用户界面组件,以管理和更新应用程序的状态。
从这里开始,您可以继续使用 styling React components来创建更具吸引力的计数用户界面。
您还可以在 DigitalOcean 上观看完整的 如何在 React.js 中编码系列,了解更多关于使用 React 开发的信息。