在 React 中設定倒數計時器

Irakli Tchigladze 2022年5月18日
在 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 中獲取起始分鐘和秒值。如果沒有分鐘和秒可以倒計時,則沒有計時器可以顯示空字串。

如果值可用,最好始終以兩位數顯示秒數以保持格式一致性,即使它是個位數。我們通過在花括號中使用模板文字來實現這一點。

正如我們所見,minssecs 值已被解構,因此我們的下一步將是這樣做。我們還提到我們將需要 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>
    )
}

我們必須開始從核心庫中匯入 useStateuseEffect 鉤子。

到目前為止,minssecs 狀態變數設定為 0,因此我們不會在螢幕上看到任何內容。但是,如果你更改 propsstartingMinutesstartingSeconds 值,你將看到倒計時的起點。在上面的程式碼中,我們還定義了更新狀態的函式。

倒計時的本質是週期性地扣除一定的時間值。為此,我們將需要 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 值更新狀態。這實際上是我們倒計時的核心功能。

下一步定義如果 secsmins 為 0 會發生什麼。在這種情況下,我們通過呼叫 clearInterval() 函式取消程式碼的重複執行。

最後,在 else 語句中,我們處理秒數達到 0 但仍有分鐘數要扣除的情況。

回撥函式是第一個引數。它包含應該重複執行的一段程式碼。

在我們的示例中,我們編寫了一個行內函數,但我們也可以很容易地單獨編寫它並在我們的 setInterval() 方法中引用它,如下所示:

setInterval(someFunction, 1000)

該示例中的第二個引數以及原始示例中的第二個引數是指延遲。它指定 setInterval() 函式應在程式碼執行之間等待多長時間。

時間值以毫秒為單位指定。在我們的示例中,我們希望倒數計時器每秒執行一次,即 1000 毫秒。

最後,useEffect() 鉤子的返回值通常用於清理訂閱和取消像 setInterval() 之類的重複函式。在我們的示例中,我們正是這樣做的,並在執行我們的 sampleInterval() 回撥函式時呼叫 clearInterval()

Irakli Tchigladze avatar Irakli Tchigladze avatar

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