React.jsで現在の時刻を表示するデジタル時計を作ってみましょう。
普通にJavaScriptの感覚で作成すると、ハマってしまうようである。
[React] 現在の日付と時刻を表示する(デジタル時計) | FEELD BLOG (feeld-uni.com)
これによると、useStateとuseEffectを使う必要があるようである。
useEffectを使わず、useStateだけで書けないかどうか考えてみます。
まずは静的なページの作成からです。
RealTimeClock.js
const RealtimeClock = ()=>{
const dateTime = new Date();
const time = dateTime.getHours() + ":"
+ dateTime.getMinutes() + ":"
+ dateTime.getSeconds();
return(
<div>
<p>{time}</p>
</div>
)
}
export default RealtimeClock;
次はボタンを押すと時刻が変わるようにします。
import {useState} from 'react';
const RealtimeClock = ()=>{
const dateTime = new Date();
const startTime = dateTime.getHours() + ":"
+ dateTime.getMinutes() + ":"
+ dateTime.getMilliseconds();
const [time,setTime] = useState(startTime);
const changeTime = ()=>{
const nextTime = dateTime.getHours() + ":"
+ dateTime.getMinutes() + ":"
+ dateTime.getSeconds();
setTime(nextTime);
}
return(
<div>
<p>{time}</p>
<button type="button" onClick={changeTime}>PUSH</button>
</div>
)
}
export default RealtimeClock;
最後は、stateが変更されれば(ここではsetTimeoutで1秒ごとにstateを変える記述を追記してます)、自動的にレンダリングされることを念頭におきながら記載すると、完成です。
import {useState} from 'react';
const RealtimeClock = ()=>{
const [time,setTime] = useState('');
const changeTime = ()=>{
const dateTime = new Date();
const nextTime = dateTime.getHours() + ":"
+ dateTime.getMinutes() + ":"
+ dateTime.getSeconds();
setTime(nextTime);
}
setTimeout(changeTime,1000);
return(
<div>
onChange={changeTime}>{time}</p>
</div>
)
}
export default RealtimeClock;
いくつか気づいた点があります。
stateの初期値と変更する値が同じなら、1回しかレンダリング(マウント)されないので、時間は初めの時刻表示でとまってしまう。
見やすくし、不要なものを削除しました。
import {useState} from 'react';
const RealtimeClock = ()=>{
const [time,setTime] = useState('');
const dateTime = new Date();
const nextTime = dateTime.getHours() + ":"
+ dateTime.getMinutes() + ":"
+ dateTime.getSeconds();
const changeTime = ()=>{
setTime(nextTime);
}
setTimeout(changeTime,1000);
return(
<div>
<p>{time}</p>
</div>
)
}
export default RealtimeClock;