Jak vytvořit odpočítávací časovač pomocí React Hooks

⭐ Úvod

React (aka ReactJS) je knihovna, která vytváří deklarativní a na komponentách založená uživatelská rozhraní. Díky zahrnutí funkčních komponent a háků je ještě účinnější v oblasti opětovné použitelnosti, lepší organizace kódu a toku dat.

Weboví vývojáři široce používají standardní háčky Reactu jako useState, useEffect ke správě stavu v rámci komponent. Nicméně praxe psaní custom hooks zdá se být o něco menší. Tento článek si klade za cíl vysvětlit použití vlastního háku způsobem přátelským pro začátečníky. Co může být lepšího, než se to naučit vývojem malé, ale praktické aplikace?

Vytvoříme countdown timer což nám umožní nastavit počáteční datum a čas zahájení odpočítávání. Jakmile datum a čas vyprší, zobrazí se upozornění na vypršení platnosti. Obrázek níže ukazuje funkční příklad aplikace.

Vezměte prosím na vědomí, že pokud jste v Reactu nováčkem a plánujete sledovat tento článek, naučíte se pojmy jako,

  • Jak strukturovat komponenty
  • Základní správa stavu pomocí standardních háčků
  • Vlastní hák pro správu odpočítávání
  • Podmíněné vykreslování pro zobrazení vypršení platnosti
  • Základní styly CSS

Zní to vzrušující? Začněme.

⭐ The Countdown aplikace

Když se učíte React, potřebujete „Thinking in React“.

Znamená to,

  • Začněte s návrhem aplikace.
  • Rozdělte jej na možné součásti.
  • Rozhodněte se pro komponentu state a data předat jako props mezi komponenty.
  • Rozhodněte se pro znovu použitelnou logiku, kterou můžete izolovat a znovu použít mezi komponentami, vítáme vlastní háčky.

Zde je návrh a členění komponent countdown aplikace. Všimněte si prosím, jak můžeme identifikovat a označit součásti.

Aplikace má uživatelské rozhraní pro zobrazení odpočítávaných čísel. Zobrazuje upozornění na vypršení platnosti, když odpočítávání vyprší. Takže můžeme rozdělit odpovědnosti do následujících složek,

  • CountdownTimer :Nadřazená komponenta, která podmíněně vykresluje odpočítávání nebo oznámení o vypršení platnosti.
  • ShowCount :Komponenta pro zobrazení odpočítávání pro dny, hodiny, minuty a sekundy.
  • DateTimeDisplay :Opakovaně použitelná prezentační komponenta, která zobrazuje počet dní, hodin, minut a sekund spolu se svými štítky.
  • ExpiredNotice :Komponenta, která zobrazuje varovný text, který říká, že časovač vypršel a jakou akci provést.

Upozorňujeme, že celý výpočet odpočítávání můžeme provést uvnitř CountdownTimer nebo ShowCount komponenty. Ale přemýšlejte o tom, tento výpočet odpočítávání můžete v budoucnu potřebovat jinde ve své aplikaci. Takže byste to neměli mít pevně spojené s žádnými součástmi.

Přivítáme Custom Hook vyřešit problém. Výpočet odpočítávání můžeme izolovat ve vlastním háku nazvaném useCountdown . Vlastní hák přijímá počáteční datum a čas a vrací počet dní, hodin, minut a sekund v intervalu dle našeho výběru (řekněme každých 1000 ms).

S tím se nyní podívejte na následující schéma.

Vidíme useCountdown háček izolovaný od hierarchie komponent. Dle potřeby dodává komponentě požadovaná data. Vidíme také podmíněné vykreslování ShowCounter a ExpiredNotice na základě hodnoty čítače. Určíme counter hodnota založená na jednotlivých hodnotách dnů, hodin, minut a sekund.

Doufám, že jste již začali "Thinking in React"! Začněme vkládat věci do kódu.

⭐ Nastavení prostředí projektu

Chcete-li pokračovat, můžete použít aplikaci Create React App (CRA) k vytvoření struktury počátečního projektu. Ujistěte se, že máte Node.js nainstalováno. Otevřete příkazový řádek/terminál a spusťte tento příkaz,

npx create-react-app countdown

Tento příkaz bude chvíli trvat a vytvoří strukturu projektu za vás. Po dokončení přejděte na countdown adresář a spusťte aplikaci lokálně pomocí následujícího příkazu

npm run start

Nebo

yarn start

Měli byste mít automaticky otevřenou kartu prohlížeče, která spouští aplikaci @ http://localhost:3000 URL. Všimněte si prosím Create React App podporuje přebíjení za tepla. To znamená, že vaše aplikace v prohlížeči se automaticky aktualizuje, když provedete jakékoli změny ve zdrojovém kódu projektu a uložíte jej.

⭐ Vlastní hák pro provedení odpočítávání

Vlastní háky jsou běžné funkce JavaScriptu, které izolují logiku opakovaně použitelné komponenty. Důležité je zde poznamenat, že můžeme sdílet stavovou logiku mezi komponenty, aniž bychom znečišťovali stavy. Pokud už nějakou dobu používáte React, děláte to samé pomocí vzorů jako Higher-Order Component , Render Props . Vlastní háčky jsou mnohem přímočařejší.

Vytvořme háček pro výpočet odpočítávání v intervalu. Vytvořte složku s názvem hooks pod číslem src vašeho projektu složku. Vytvořte soubor s názvem useCountdown.js s následujícím obsahem.

import { useEffect, useState } from 'react';

const useCountdown = (targetDate) => {
  const countDownDate = new Date(targetDate).getTime();

  const [countDown, setCountDown] = useState(
    countDownDate - new Date().getTime()
  );

  useEffect(() => {
    const interval = setInterval(() => {
      setCountDown(countDownDate - new Date().getTime());
    }, 1000);

    return () => clearInterval(interval);
  }, [countDownDate]);

  return getReturnValues(countDown);
};

const getReturnValues = (countDown) => {
  // calculate time left
  const days = Math.floor(countDown / (1000 * 60 * 60 * 24));
  const hours = Math.floor(
    (countDown % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
  );
  const minutes = Math.floor((countDown % (1000 * 60 * 60)) / (1000 * 60));
  const seconds = Math.floor((countDown % (1000 * 60)) / 1000);

  return [days, hours, minutes, seconds];
};

export { useCountdown };

Zde je několik věcí, které je třeba zmínit o výše uvedeném kódu,

  • Je to běžná funkce JavaScriptu, která přijímá cílové datum a čas pro zahájení odpočítávání. Všimněte si však názvu funkce (háčku). Musí začínat slovem use splnit konvence React.
  • Používá setInterval metoda rozhraní API prohlížeče pro výpočet volného času každou sekundu (1000 milisekund).
  • Provede výpočet, aby zjistil dny, hodiny, minuty a sekundy.
  • Nakonec vrátí hodnotu dnů, hodin, minut a sekund v každém intervalu. Upozorňujeme, že jelikož zde musíme vracet více hodnot, můžeme je vrátit jako pole nebo objekt. Rozhodli jsme se vrátit všechny hodnoty v poli.
  • Standardní háček useEffect také pomáhá s životním cyklem součásti a provádí nezbytné čištění, jako je vymazání intervalu.

Dobře, teď je čas použít tento háček.

⭐ Rozdělení CountdownTimer Komponenta

Nyní použijeme useCountdown zavěsit do komponenty. Vytvořte prosím soubor CountdownTimer.js pod src složku s následujícím obsahem,

import React from 'react';
import { useCountdown } from './hooks/useCountdown';

const CountdownTimer = ({ targetDate }) => {
  const [days, hours, minutes, seconds] = useCountdown(targetDate);

  if (days + hours + minutes + seconds <= 0) {
    return <ExpiredNotice />;
  } else {
    return (
      <ShowCounter
        days={days}
        hours={hours}
        minutes={minutes}
        seconds={seconds}
      />
    );
  }
};

Jak vidíte v kódu výše,

  • Nejprve importujeme useCountdown háček k použití.
  • Ve komponentní funkci voláme háček předáním targetDate . My vám dodáme tento targetDate za chvíli z jiné složky. Tento mechanismus sdílení informací mezi komponentami se nazývá sdílení podle props . Zde je targetDate je rekvizita.
  • Dále zkontrolujeme, zda vypršel čas. V případě vypršení času vykreslíme ExpriredNotice komponent. Jinak vykreslíme ShowCounter komponentu se všemi daty z háku. Tento mechanismus podmíněného vracení komponent se nazývá Conditional Rendering .

Dále vytvoříme ExpiredNotice a ShowCounter komponenty.

⭐ Komponenta pro zobrazení zprávy o vypršení platnosti

Přidejte prosím následující kód za příkazy importu v CountdownTimer.js soubor.

const ExpiredNotice = () => {
  return (
    <div className="expired-notice">
      <span>Expired!!!</span>
      <p>Please select a future date and time.</p>
    </div>
  );
};

Jednoduchá komponenta zobrazuje text Expired!!! s poznámkou.

⭐ Komponenta pro zobrazení odpočítávání

Nyní přidáme komponentu pro zobrazení skutečného odpočítávání. Přidejte prosím následující kód za ExpiredNotice komponentu, kterou jsme vytvořili výše.

const ShowCounter = ({ days, hours, minutes, seconds }) => {
  return (
    <div className="show-counter">
      <a
        href="https://tapasadhikary.com"
        target="_blank"
        rel="noopener noreferrer"
        className="countdown-link"
      >
        <DateTimeDisplay value={days} type={'Days'} isDanger={days <= 3} />
        <p>:</p>
        <DateTimeDisplay value={hours} type={'Hours'} isDanger={false} />
        <p>:</p>
        <DateTimeDisplay value={minutes} type={'Mins'} isDanger={false} />
        <p>:</p>
        <DateTimeDisplay value={seconds} type={'Seconds'} isDanger={false} />
      </a>
    </div>
  );
};

Podívejte se blíže na výše uvedený kód. Zobrazuje každou z hodnot (dny, hodiny, minuty a sekundy) pomocí komponenty nazvané DateTimeDisplay které nyní tvoříme. Ale všimněte si rekvizit, které předáváme této komponentě, zejména isDanger .

Můžeme předat výraz pomocí isDanger podporuje stylování konkrétního zobrazení, když je výraz vyhodnocen jako pravdivý. Například chceme days zčervená, když odpočítávání dosáhne posledních 3 dnů!

Vytvořte soubor s názvem DateTimeDisplay.js pod src složku s následujícím obsahem,

import React from 'react';

const DateTimeDisplay = ({ value, type, isDanger }) => {
  return (
    <div className={isDanger ? 'countdown danger' : 'countdown'}>
      <p>{value}</p>
      <span>{type}</span>
    </div>
  );
};

export default DateTimeDisplay;

Je to další jednoduchá součást, která vykresluje hodnotu a typ. Nyní můžeme tuto komponentu importovat do nadřazené komponenty (CountdownTimer) jako,

import DateTimeDisplay from './DateTimeDisplay';

To je většina.

⭐ The Complete CountdownTimer Komponenta

Zde je CountdownTimer.js obsah zatím vypadá.

import React from 'react';
import DateTimeDisplay from './DateTimeDisplay';
import { useCountdown } from './hooks/useCountdown';

const ExpiredNotice = () => {
  return (
    <div className="expired-notice">
      <span>Expired!!!</span>
      <p>Please select a future date and time.</p>
    </div>
  );
};

const ShowCounter = ({ days, hours, minutes, seconds }) => {
  return (
    <div className="show-counter">
      <a
        href="https://tapasadhikary.com"
        target="_blank"
        rel="noopener noreferrer"
        className="countdown-link"
      >
        <DateTimeDisplay value={days} type={'Days'} isDanger={days <= 3} />
        <p>:</p>
        <DateTimeDisplay value={hours} type={'Hours'} isDanger={false} />
        <p>:</p>
        <DateTimeDisplay value={minutes} type={'Mins'} isDanger={false} />
        <p>:</p>
        <DateTimeDisplay value={seconds} type={'Seconds'} isDanger={false} />
      </a>
    </div>
  );
};

const CountdownTimer = ({ targetDate }) => {
  const [days, hours, minutes, seconds] = useCountdown(targetDate);

  if (days + hours + minutes + seconds <= 0) {
    return <ExpiredNotice />;
  } else {
    return (
      <ShowCounter
        days={days}
        hours={hours}
        minutes={minutes}
        seconds={seconds}
      />
    );
  }
};

export default CountdownTimer;

⭐ Pomocí CountdownTimer

Pojďme nyní použít komponentu CountdownTimer s cílovým datem a uvidíme, jak to funguje! Otevřete prosím App.js soubor a nahraďte jeho obsah následujícím kódem,

import React from 'react';
import CountdownTimer from './CountdownTimer';

import './App.css';

export default function App() {
  const THREE_DAYS_IN_MS = 3 * 24 * 60 * 60 * 1000;
  const NOW_IN_MS = new Date().getTime();

  const dateTimeAfterThreeDays = NOW_IN_MS + THREE_DAYS_IN_MS;

  return (
    <div>
      <h1>Countdown Timer</h1>
      <CountdownTimer targetDate={dateTimeAfterThreeDays} />
    </div>
  );
}

Jak vidíte, používáme CountdownTimer komponenta s cílovým datem tři dny od now . Zkontrolujte prosím aplikaci v prohlížeči. Měli byste zjistit, že odpočítávání funguje. Nevypadá to příjemně, ale funguje to!

⭐ Pojďme přidat styly

Pojďme trochu vylepšit vzhled a dojem. Přidejme nějaké styly. Otevřete prosím soubor App.css v editoru a nahraďte obsah následujícím,

.expired-notice {
  text-align: center;
  padding: 2rem;
  border: 1px solid #ebebeb;
  border-radius: 0.25rem;
  margin: 0.5rem;
}

.expired-notice > span {
  font-size: 2.5rem;
  font-weight: bold;
  color: red;
}

.expired-notice > p {
  font-size: 1.5rem;
}

.show-counter {
  padding: 0.5rem;
}

.show-counter .countdown-link {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  font-weight: 700;
  font-size: 1.25rem;
  line-height: 1.75rem;
  padding: 0.5rem;
  border: 1px solid #ebebeb;
  border-radius: 0.25rem;
  text-decoration: none;
  color: #000;
}

.show-counter .countdown {
  line-height: 1.25rem;
  padding: 0 0.75rem 0 0.75rem;
  align-items: center;
  display: flex;
  flex-direction: column;
}

.show-counter .countdown.danger {
  color: #ff0000;
}

.show-counter .countdown > p {
  margin: 0;
}

.show-counter .countdown > span {
  text-transform: uppercase;
  font-size: 0.75rem;
  line-height: 1rem;
}

Mělo by to stačit. Nyní bude aplikace vypadat mnohem lépe. Zde je změněný vzhled odpočítávacího časovače, když ukazuje počítadla.

Zde je návod, jak vypršelo odpočítávání. Můžete to otestovat změnou cílového data na nějaké minulé datum v App.js soubor.

A je to. Skvělá zpráva, vyvinuli jste super skvělý odpočítávací časovač pomocí vlastního háku a dalších konceptů React.

⭐ Úkol pro vás:Rozšiřte aplikaci

Veškerý zdrojový kód použitý v tomto článku naleznete v tomto stackblitz projekt. Prosím, for fort, změnit a zlepšit to.

https://stackblitz.com/edit/react-hook-countdown?file=src/App.js

Zde je nápad, jak aplikaci dále rozšířit. Můžete použít Date-Time Picker vyberte datum a čas podle svého výběru a předejte jej odpočítávacímu časovači. Zde je navrhované rozhraní vylepšené funkce. Zkuste to prosím.

V případě, že se zaseknete nebo budete potřebovat pomoc, můžete pracovní kód najít v tomto úložišti.

https://github.com/atapas/react-play

⭐ Závěr

Nejlepší způsob, jak se naučit React, je naučit se ho prakticky pomocí mnoha jednoduchých, ale účinných projektů, jako je ten, o kterém jsme zde diskutovali. Musíte rozpoznat a naplánovat koncepty React, které můžete v takových projektech použít. Hledejte příležitosti k aplikaci různých konceptů React do jednoho. Nedělejte z projektů velké projekty zároveň.

Využijte potenciál Custom Hooks . Kdekoli cítíte potřebu stavové znovupoužitelné logiky uvnitř komponenty, je čas přemýšlet o jejím vytvoření jako háků.

Pokud s Reactem začínáte nebo se chcete učit prakticky, založil jsem YouTube Series pro to. Neváhejte se na to podívat a PŘIHLÁSIT SE.

https://www.youtube.com/playlist?list=PLIJrr73KDmRyrDnDFy-hHvQ24rRjz6e_J

Pojďme se spojit. Sdílím své poznatky o JavaScriptu, vývoji webu, kariéře a tvorbě obsahu také na těchto platformách,

  • Sledujte mě na Twitteru
  • Přihlaste se k odběru mého kanálu YouTube
  • Vedlejší projekty na GitHubu
  • Výkladní skříň