はじめに
- 会員登録機能でユーザーに誕生日を登録して持ったので、誕生日までのカウントダウンコンポーネントを作成しようと思いましたが、 指定の時間を入力して、入力した時間のカウントダウンのコンポーネントを作成することにしました。
- 時間の操作はmomentを利用して簡易的に行う
- スタートボタンがクリックされたときに「開始」とメッセージを通知し、タイムオーバー時に「終了」というメッセージを通知する処理にしてみました。
コード
もっと効率的な書き方で書き直したい。
import React, { useEffect, useState } from 'react' import moment from 'moment' const CountDownTimer = () => { const [timeLeft, setTimeLeft] = useState({}); const [timeNow, setTimeNow] = useState(0); const [timeHour, setTimeHour] = useState(0); const [timeMin, setTimeMin] = useState(0); const [timeSec, setTimeSec] = useState(0); const timerComponents = []; const calculateTimeLeft = () => { let timeLeft = {}; if ((timeHour > 0) || (timeMin > 0) || (timeSec > 0)) { const difference = timeNow - moment().unix() console.log(difference) if (difference > -1) { timeLeft = { '日': Math.floor(difference / (60 * 60 * 24)), '時間': Math.floor((difference / (60 * 60)) % 24), '分': Math.floor((difference / 60) % 60), '秒': Math.floor((difference) % 60) }; } if (difference == 0) { const endAnnounce = new SpeechSynthesisUtterance("終了") speechSynthesis.speak(endAnnounce) } } return timeLeft; }; useEffect( () => { if (timeNow > 0 ){ let timer1 = setTimeout(() => { const result = calculateTimeLeft() if (Object.keys(result).length > 0){ setTimeLeft(result) } }, 1000) return () => { clearTimeout(timer1) } } } ) Object.keys(timeLeft).forEach(interval => { if (!timeLeft[interval]) { return; } timerComponents.push( <span> {timeLeft[interval]} {interval}{" "} </span> ); }); const endTime = () => { return (<span>時間が来ました。</span>) } const startTime = (e) => { const startAnnounce = new SpeechSynthesisUtterance("開始") speechSynthesis.speak(startAnnounce) setTimeNow(moment().add(timeHour, 'hours').add(timeMin, 'minutes').add((Number(timeSec)+1), 'seconds').unix()) } return ( <div> <input name="min" type="number" value={timeHour} onChange={(e) => { setTimeHour(e.target.value) }} />時 <input name="min" type="number" value={timeMin} onChange={(e) => { setTimeMin(e.target.value) }} />分 <input name="sec" type="number" value={timeSec} onChange={(e) => { setTimeSec(e.target.value) }} />秒<br /> <input type="button" value="スタート" onClick={startTime}/> {timerComponents.length ? timerComponents : endTime()} </div> ); } export default CountDownTimer
画面