웹사이트 검색

React Hooks로 카운트다운 타이머를 만드는 방법


소개

이 자습서에서는 React 후크를 사용하여 카운트다운 타이머를 생성하여 React 구성 요소에서 상태를 업데이트하고 부작용을 관리합니다.

React 후크를 사용하면 더 깔끔한 코드, 구성 요소 간에 재사용 가능한 논리를 생성하고 클래스 없이 상태를 업데이트할 수 있습니다.

카운트다운 타이머는 일반적인 UI 구성요소입니다. 사용자에게 작업을 수행한 기간 또는 일부 이벤트가 발생할 때까지 남은 시간을 알릴 수 있습니다. 이 튜토리얼에서 카운트다운할 이벤트는 DigitalOcean의 Hacktoberfest입니다.

이 튜토리얼이 끝나면 React의 useState()useEffect() 후크를 사용하여 기능적이고 재사용 가능한 카운트다운 타이머를 갖게 됩니다.

전제 조건

이 가이드를 시작하기 전에 다음이 필요합니다.

  • Ubuntu 18.04에 Node.js를 설치하는 방법을 실행하는 개발 환경이 필요합니다.
  • 이 자습서에서는 Create React App을 사용하여 React 프로젝트를 설정하는 방법으로 앱을 만듭니다.
  • 또한 Mozilla 개발자 네트워크에서 찾을 수 있는 JavaScript에 대한 기본 지식이 필요합니다.

이 튜토리얼은 Node.js v16.13.1, npm v8.2.0 및 react v17.0.2에서 검증되었습니다.

1단계 - 빈 프로젝트 만들기

이 단계에서는 Create React App을 사용하여 새 프로젝트를 만듭니다. 그런 다음 프로젝트를 부트스트랩할 때 설치되는 샘플 프로젝트 및 관련 파일을 삭제합니다.

시작하려면 새 프로젝트를 만듭니다. 터미널에서 다음 스크립트를 실행하여 create-react-app를 사용하여 새 프로젝트를 설치합니다.

  1. npx create-react-app react-hooks-timer

프로젝트가 완료되면 다음 디렉터리로 변경합니다.

  1. cd react-hooks-timer

새 터미널 탭이나 창에서 Create React App 시작 스크립트를 사용하여 프로젝트를 시작합니다. 브라우저는 변경 시 자동으로 새로 고쳐지므로 작업하는 동안 이 스크립트를 실행 상태로 두십시오.

  1. npm start

로컬 실행 서버를 얻게 됩니다. 프로젝트가 브라우저 창에서 열리지 않으면 http://localhost:3000/로 열 수 있습니다. 원격 서버에서 실행 중인 경우 주소는 http://your_server_ip:3000입니다.

Create React App에 의해 생성된 React 애플리케이션이 브라우저에 로드됩니다.

새로운 사용자 지정 구성 요소 세트를 빌드할 것이므로 빈 프로젝트를 가질 수 있도록 일부 상용구 코드를 삭제하는 것부터 시작해야 합니다.

시작하려면 텍스트 편집기에서 src/App.js를 엽니다. 이것은 페이지에 주입되는 루트 구성 요소입니다. 여기에서 모든 구성 요소가 시작됩니다. Create React App으로 React 프로젝트를 설정하는 방법에서 App.js에 대한 자세한 정보를 찾을 수 있습니다.

다음 명령으로 src/App.js를 엽니다.

  1. nano src/App.js

다음과 같은 파일이 표시됩니다.

import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

그런 다음 return 문의 모든 항목을 교체하여 <div> 태그 집합을 반환합니다. 이렇게 하면 아무 것도 반환하지 않는 유효한 페이지가 제공됩니다. 최종 코드는 다음과 같습니다.

import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div>
    </div>
  )
}

export default App;

다음으로 로고를 제거합니다. import logo from ./logo.svg; 줄을 삭제합니다.

텍스트 편집기를 저장하고 종료합니다.

마지막으로, 이 응용 프로그램에서 사용하지 않을 것이므로 로고를 삭제하십시오. 혼란을 피하기 위해 작업할 때 사용하지 않는 파일을 제거하는 것이 좋습니다.

터미널 창에서 다음 명령을 입력합니다.

  1. rm src/logo.svg

이제 프로젝트가 설정되었으므로 첫 번째 구성 요소를 만들 수 있습니다.

2단계 - 남은 시간 계산하기

이 단계에서는 현재 날짜와 Hacktoberfest 첫날 사이의 남은 시간을 계산하는 함수를 만듭니다.

먼저 calculateTimeLeft라는 함수를 설정합니다.

// ...

const calculateTimeLeft = () => {

};

// ...

다음으로 함수 내에서 JavaScript Date 개체를 사용하여 현재 연도를 찾습니다.

JavaScript date 메서드 Date.getFullYear()로 설정되는 year라는 변수를 만듭니다.

calculateTimeLeft 함수 내에 다음 코드를 추가합니다.

// ...

const calculateTimeLeft = () => {
  let year = new Date().getFullYear();
}

// ...

참고: JavaScript Date 개체를 사용하여 날짜 및 시간 작업을 할 수 있습니다.

Date.getFullYear() 메서드는 현재 연도를 가져옵니다.

이제 이 변수를 사용하여 현재 날짜와 Hacktoberfest 첫날 간의 차이를 계산할 수 있습니다.

calculateTimeLeft 함수 내부에 difference라는 새 변수를 추가합니다. 다음 코드를 사용하여 새 Date 개체와 동일하게 설정합니다.

// ...

const calculateTimeLeft = () => {
  let year = new Date().getFullYear();

  const difference = +new Date(`10/01/${year}`) - +new Date();
}

// ...

Date 객체 앞의 +는 객체를 정수로 캐스팅하도록 JavaScript에 지시하는 속기입니다. 이는 에포크 이후 마이크로초로 표시되는 객체의 Unix 타임스탬프를 제공합니다.

참고: 이 자습서에서는 카운트다운 날짜를 미래로 설정해야 합니다. 그렇지 않으면 오류가 발생합니다.

코드를 재사용 가능하게 유지하려면 JavaScript 템플릿 리터럴을 사용하고 Hacktoberfest의 월 및 일과 함께 year 변수를 추가합니다. Hacktoberfest는 매년 10월 1일에 시작합니다. 하드 코딩된 연도 대신 연도 변수를 사용하면 항상 현재 연도가 표시됩니다.

카운트다운 타이머가 만료될 때까지의 총 밀리초 수를 계산했으므로 밀리초 수를 보다 친숙하고 사람이 읽을 수 있는 값으로 변환해야 합니다.

3단계 - 일, 시, 분, 초 형식 지정

이 단계에서는 timeLeft라는 빈 개체를 생성하고 if 문을 사용하여 남은 시간이 있는지 확인하고 총 시간, 분 및 시간을 계산합니다. 수학 및 모듈러스(%) 연산자를 사용하여 초. 마지막으로 timeLeft를 반환합니다.

먼저 timeLeft라는 빈 개체를 만든 다음 if 문에서 일, 시, 분, 초로 채워집니다.

calculateTimeLeft 함수 내에 다음 코드를 추가합니다.

// ...

const calculateTimeLeft = () => {
  let year = new Date().getFullYear();
  let difference = +new Date(`10/01/${year}`) - +new Date();

  let timeLeft = {};
}

// ...

이제 difference 변수를 비교하여 0보다 큰지 확인하는 if 문을 만듭니다.

calculateTimeLeft 함수 안에 다음 코드를 추가합니다.

// ...

const calculateTimeLeft = () => {
  let year = new Date().getFullYear();
  let difference = +new Date(`10/01/${year}`) - +new Date();

  let timeLeft = {};

  if (difference > 0) {
    timeLeft = {
      days: Math.floor(difference / (1000 * 60 * 60 * 24)),
      hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
      minutes: Math.floor((difference / 1000 / 60) % 60),
      seconds: Math.floor((difference / 1000) % 60)
    };
  }
}

// ...

이 코드에서는 일, 시, 분, 초의 숫자를 반올림하고 나머지를 삭제하여 정수 값을 얻습니다. 그런 다음 차이를 비교하여 0보다 큰지 확인할 수 있습니다.

마지막으로 구성 요소의 다른 곳에서 값을 사용할 수 있도록 timeLeft를 반환해야 합니다.

calculateTimeLeft 함수 안에 다음 코드를 추가합니다.

// ...

const calculateTimeLeft = () => {
  let year = new Date().getFullYear();
  let difference = +new Date(`10/01/${year}`) - +new Date();

  let timeLeft = {};

  if (difference > 0) {
    timeLeft = {
      days: Math.floor(difference / (1000 * 60 * 60 * 24)),
      hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
      minutes: Math.floor((difference / 1000 / 60) % 60),
      seconds: Math.floor((difference / 1000) % 60)
    };
  }

  return timeLeft;
}

// ...

이제 Hacktoberfest까지 남은 시간을 계산하는 함수를 만들었으므로 타이머를 제어하고 업데이트할 앱 상태를 추가할 수 있습니다.

4단계 — useState 및 useEffect로 앱 상태 업데이트

React Hooks를 사용하면 기존 기능 구성 요소를 클래스로 변환하지 않고도 상태 관리 기능을 추가할 수 있습니다.

이 단계에서는 이 구성 요소의 상태를 관리하기 위해 React에서 useStateuseEffect 후크를 가져옵니다.

App.js 파일 맨 위에서 가져오기 문에 useStateuseEffect를 추가합니다.

import React, { useEffect, useState } from "react";

// ...

이 코드는 React에서 사용할 수 있는 이러한 특정 후크와 해당 기능을 사용하고 싶다고 React에 알립니다.

카운트다운 타이머가 작동하도록 하려면 이전에 상태를 업데이트하도록 코딩한 남은 시간 메서드를 연결해야 합니다.

calculateTimeLeft 함수 뒤에 다음 코드를 추가합니다.

// ...

const [timeLeft, setTimeLeft] = useState(calculateTimeLeft());

// ...

JavaScript 구문을 배열 분해라고 합니다.

useState 메서드는 초기 상태를 설정하는 매개변수를 받아들이고 현재 상태를 포함하는 배열과 상태를 설정하는 함수를 반환합니다.

timeLeft는 간격의 남은 시간 개체를 전달하고 상태를 설정하는 방법을 제공합니다. 구성요소 로드 시 timeLeft 값은 현재 남은 시간 값으로 설정됩니다.

다음으로 useEffect 후크를 사용하여 구성 요소 부작용을 처리합니다.

참고: 부작용은 실행 중인 함수의 범위 밖에 있는 것에 영향을 미치는 모든 것입니다.

이 솔루션에서는 useEffect 후크 내에서 setTimeout 메서드를 사용합니다. setTimeout 및 유사한 setInterval 메서드는 useEffect 후크 내부에서 사용될 때 일반적인 React 패턴입니다.

React의 setTimeout 메서드와 같은 대부분의 비동기 동작은 useEffectuseState 후크의 조합으로 정의됩니다.

참고: React Docs의 이 섹션에서 setTimeoutsetInterval과 같은 메서드를 사용하는 시기와 방법에 대해 자세히 알아볼 수 있습니다.

useState() 함수 뒤에 이 코드를 추가합니다.

// ...

const [timeLeft, setTimeLeft] = useState(calculateTimeLeft());

useEffect(() => {
  const timer = setTimeout(() => {
    setTimeLeft(calculateTimeLeft());
  }, 1000);
});

// ...

useEffect는 남은 시간을 업데이트하는 것입니다. 기본적으로 React는 렌더링할 때마다 효과를 다시 호출합니다.

변수 timeLeft가 상태에서 업데이트될 때마다 useEffect가 실행됩니다. 이 이벤트가 발생할 때마다 타이머를 1초(또는 1,000ms)로 설정하여 해당 시간이 경과한 후 남은 시간을 업데이트합니다.

그 후 매초마다 주기가 계속됩니다.

누적 시간 초과 및 오류 발생 가능성을 제거하려면 useEffect 후크 내부에도 clearTimeout 메서드를 추가하세요.

clearTimeout 메서드를 추가하고 타이머 변수를 매개변수로 전달합니다.

// ...

useEffect(() => {
  const timer = setTimeout(() => {
    setTimeLeft(calculateTimeLeft());
  }, 1000);

  return () => clearTimeout(timer);
});

// ...

return 함수는 useEffect가 구성 요소의 첫 번째 실행을 제외하고 timer를 실행할 때마다 실행되며 구성 요소가 다음과 같은 경우 시간 초과를 지웁니다. 말 타지 않은.

이제 상태가 calculateTimeLeft() 개체로 설정되고 효과 후크 내에서 업데이트되므로 디스플레이 구성 요소를 빌드하는 데 사용할 수 있습니다.

5단계 - Object.keys 사용

이 단계에서는 Object.keys를 사용하여 timeLeft 개체를 반복하고 디스플레이 구성 요소를 구축합니다. 디스플레이 구성 요소를 사용하여 Hacktoberfest가 시작되기 전에 남은 시간을 표시합니다.

먼저 timerComponents라는 useEffect 후크 아래에 새 변수를 만듭니다.

// ...

const timerComponents = [];

// ...

timeLeft의 키를 반복한 후 이 변수를 사용하여 남은 시간으로 새 JSX 구성 요소를 푸시합니다.

다음으로 Object.keys를 사용하여 calculateTimeLeft 함수에서 반환한 timeLeft 객체를 반복합니다.

timerComponents 변수에 다음 코드를 추가합니다.

// ...

const timerComponents = [];

Object.keys(timeLeft).forEach((interval) => {
  if (!timeLeft[interval]) {
    return;
  }

  timerComponents.push(
    <span>
      {timeLeft[interval]} {interval}{" "}
    </span>
  );
});

// ...

여기서 코드는 timeLeft 개체의 속성을 통해 반복됩니다. 타이머 간격의 값이 0보다 크면 timerComponents 배열에 요소를 추가합니다.

참고: 코드의 추가 {\ \}는 남은 시간을 표시하는 간격이 화면에 표시될 때 서로 겹치지 않도록 사용됩니다.

{}를 사용하면 JSX 내에서 자바스크립트를 사용할 수 있고 \\는 공간을 추가할 수 있습니다.

이제 앱 구성요소 return 문에 새로운 JSX를 추가하여 Hacktoberfest까지 남은 시간을 표시할 준비가 되었습니다.

6단계 - 남은 시간 표시

이 단계에서는 앱 구성 요소의 return 문에 JSX 구성 요소를 추가합니다. 남은 시간이 있는지 또는 Hacktoberfest 시간인지 확인하기 위해 삼항 연산자를 사용합니다.

timerComponents 배열을 사용하려면 길이를 확인하고 반환하거나 타이머가 이미 경과했음을 사용자에게 알려야 합니다.

return 문 안에 다음 코드를 추가합니다.

// ...

return (
  <div>
    {timerComponents.length ? timerComponents : <span>Time's up!</span>}
  </div>
);

// ...

React JSX 구성 요소에서는 JavaScript if 문 대신 삼항 연산자를 사용합니다. 이는 JSX 내에서 표현식만 허용되기 때문입니다.

timerComponents.length 코드 줄은 timerComponents 배열 내부에 어떤 것이 있는지 확인하고 있으면 렌더링하고 그렇지 않으면 Times up!.

다음으로 return 문에 두 개의 JSX 구성 요소를 더 추가하여 사용자에게 카운트다운이 무엇인지 알립니다.

// ...

return (
  <div>
    <h1>Hacktoberfest 2020 Countdown</h1>
    <h2>With React Hooks!</h2>
    {timerComponents.length ? timerComponents : <span>Time's up!</span>}
  </div>
);

// ...

2020을 하드 코딩하는 대신 현재 연도를 사용하려면 새 상태 변수를 만들고 초기 상태를 new Date().getFullYear();로 설정할 수 있습니다.

첫 번째 useState() 변수 뒤에 다음 코드를 추가합니다.

// ...

const [timeLeft, setTimeLeft] = useState(calculateTimeLeft());
const [year] = useState(new Date().getFullYear());

// ...

이 메서드는 calculateTimeLeft 함수에서 사용한 현재 연도를 가져옵니다.

그런 다음 h1에서 하드코딩된 2020을 제거하고 year로 바꿀 수 있습니다.

// ...

return (
  <div>
    <h1>Hacktoberfest {year} Countdown</h1>
    <h2>With React Hooks!</h2>
    {timerComponents.length ? timerComponents : <span>Time's up!</span>}
  </div>
);

// ...

이렇게 하면 현재 연도가 항상 있는 상태 변수가 표시됩니다. 완료된 프로젝트는 다음과 같습니다.

전체 코드를 보려면 이 GitHub 리포지토리를 확인하십시오.

결론

이 자습서에서는 useStateuseEffect 후크를 사용하여 카운트다운 UI 구성 요소를 빌드하여 애플리케이션의 상태를 관리하고 업데이트했습니다.

여기에서 React 구성 요소의 스타일을 지정하여 학습을 계속하여 더 매력적인 카운트다운 UI를 만들 수 있습니다.

또한 DigitalOcean의 전체 React.js 코딩 방법 시리즈를 따라 React를 사용한 개발에 대해 더 자세히 알아볼 수 있습니다.