在 React 中设置倒数计时器
在 React 中构建的现代 Web 应用程序通常涉及跟踪时间。例如,如果你有一个博客,则每篇文章都必须显示其日期以及自发布以来经过了多长时间。
React 应用程序可以具有多种功能。在 JavaScript 中实现倒数计时器可能非常困难。它涉及操作日期值或格式化它们。
让我们看一下 React 应用程序中倒计时的示例实现。
React 中倒数计时器的实现
一般来说,所有 React 框架中的倒数计时器都是以相同的方式构建的。组件是 React 应用程序的主要构建块。
在本例中,我们将为倒数计时器构建一个功能组件。我们将使用钩子来维护状态和管理副作用。
在 React 中使用 useState()
和 useEffect()
钩子设置倒数计时器
函数式 React 组件可以有不同的结构,但它们都遵循相同的基本模式。让我们设置一个函数并将其命名为 Countdown
。
大概,你将在父组件中使用该组件,因此我们也应该接受 props
。
export default function Countdown(props){
return (
<div>
{!(mins && secs) ? "" : (
<p>
{" "}
{mins}:{secs < 10 ? `0${secs}` : secs}
</p>
)}
</div>
)
}
到目前为止,这非常简单。我们将从 props 中获取起始分钟和秒值。如果没有分钟和秒可以倒计时,则没有计时器可以显示空字符串。
如果值可用,最好始终以两位数显示秒数以保持格式一致性,即使它是个位数。我们通过在花括号中使用模板文字来实现这一点。
正如我们所见,mins
和 secs
值已被解构,因此我们的下一步将是这样做。我们还提到我们将需要 useState()
和 useEffect()
挂钩。前者对于跟踪不断变化的时代是必要的。
如果我们使用类组件,我们将使用生命周期方法来处理时间的变化。我们可以将 useEffect()
钩子用于具有许多生命周期方法特性的功能组件。
因此,事不宜迟,让我们将钩子引入我们的应用程序:
import React from "react";
import { useState, useEffect } from "react";
export default function Countdown(props){
const { startingMinutes = 0, startingSeconds = 0 } = props;
const [mins, setMinutes] = useState(startingMinutes);
const [secs, setSeconds] = useState(startingSeconds);
return (
<div>
{!(mins && secs) ? "" : (
<p>
{" "}
{mins}:{secs < 10 ? `0${secs}` : secs}
</p>
)}
</div>
)
}
我们必须开始从核心库中导入 useState
和 useEffect
钩子。
到目前为止,mins
和 secs
状态变量设置为 0,因此我们不会在屏幕上看到任何内容。但是,如果你更改 props
的 startingMinutes
和 startingSeconds
值,你将看到倒计时的起点。在上面的代码中,我们还定义了更新状态的函数。
倒计时的本质是周期性地扣除一定的时间值。为此,我们将需要 setInterval()
方法。它每隔指定的时间执行一段代码。
在这种情况下,每经过一秒,我们必须将总秒数减少 1。每 60 秒一次,我们还必须将起始分钟数减少 1。
我们完成的应用程序将如下所示:
import React from "react";
import { useState, useEffect } from "react";
export default function Countdown(props) {
const { startingMinutes = 111, startingSeconds = 0 } = props;
const [mins, setMinutes] = useState(startingMinutes);
const [secs, setSeconds] = useState(startingSeconds);
useEffect(() => {
let sampleInterval = setInterval(() => {
if (secs > 0) {
setSeconds(secs - 1);
}
if (secs === 0) {
if (mins === 0) {
clearInterval(sampleInterval);
} else {
setMinutes(mins - 1);
setSeconds(59);
}
}
}, 1000);
return () => {
clearInterval(sampleInterval);
};
});
return (
<div>
{!(mins && secs) ? "" : (
<p>
{" "}
{mins}:{secs < 10 ? `0${secs}` : secs}
</p>
)}
</div>
);
}
这里有很多东西要解开。首先,让我们解释一下 setInterval()
回调的逻辑,因为这是每隔指定时间执行一次的代码。
首先,我们检查 secs
状态值是否大于 0,如果是,我们使用 secs - 1
值更新状态。这实际上是我们倒计时的核心功能。
下一步定义如果 secs
和 mins
为 0 会发生什么。在这种情况下,我们通过调用 clearInterval()
函数取消代码的重复执行。
最后,在 else
语句中,我们处理秒数达到 0 但仍有分钟数要扣除的情况。
回调函数是第一个参数。它包含应该重复执行的一段代码。
在我们的示例中,我们编写了一个内联函数,但我们也可以很容易地单独编写它并在我们的 setInterval()
方法中引用它,如下所示:
setInterval(someFunction, 1000)
该示例中的第二个参数以及原始示例中的第二个参数是指延迟。它指定 setInterval()
函数应在代码执行之间等待多长时间。
时间值以毫秒为单位指定。在我们的示例中,我们希望倒数计时器每秒执行一次,即 1000 毫秒。
最后,useEffect()
钩子的返回值通常用于清理订阅和取消像 setInterval()
之类的重复函数。在我们的示例中,我们正是这样做的,并在执行我们的 sampleInterval()
回调函数时调用 clearInterval()
。
Irakli is a writer who loves computers and helping people solve their technical problems. He lives in Georgia and enjoys spending time with animals.
LinkedIn