Reactでカウントダウンタイマーを作る
前提
code:timer.html
<!DOCTYPE html>
<head>
<title>timer.html</title>
<script type="module" src="timer.js"></script>
</head>
<body></body>
timer.jsは以下のコマンドで作成する
$ deno bundle timer.tsx timer.js
クラスコンポーネントを作る
code:timer.tsx
/// <reference no-default-lib="true" />
/// <reference lib="esnext" />
/// <reference lib="dom" />
interface CountdownTimerProps {
time: number;
}
interface CountdownTimerState {
time: number;
}
class CountdownTimer extends React.Component<
CountdownTimerProps, // propsの型
CountdownTimerState // stateの型
{
constructor(props: CountdownTimerProps) {
// 初期化
super(props);
this.state = { time: props.time };
}
render(): JSX.Element {
// 描画
return <input type="text" disabled value={this.state.time} />;
}
}
const root = createRoot(document.body);
root.render(<CountdownTimer time={10} />);
すっごくごちゃごちゃしているけれど、大事なのは以下の行
23. CountdownTimerというクラスを定義している
この中にカウント中の数値を保存して、カウントダウンの処理に使う
29. super(props)は書かなければいけないものとして覚えよう
この関数の戻り値がブラウザ上で描画される
value属性に表示する数値を渡している
39. root(<body>)の直下にCountdownTimerを描画する timeにnumber型の10を渡している
この値はCountdownTimerのprops.timeの中に格納される
実行すると、ブラウザ上に10が入ったテキストボックスが1つ出現する
https://gyazo.com/e71eb0ed049140bdfa4cf74f61eb1020
今は何も動かないが、これを毎秒1ずつ減らしていく処理をこれから書く
カウントダウンの処理を書く
code:timer.tsx
class CountdownTimer extends React.Component<
CountdownTimerProps, // propsの型
CountdownTimerState // stateの型
{
//(中略)
componentDidMount() {
// DOMが描画された後に最初に呼び出される処理
this.timerID = setInterval(
() => this.tick(), // tick関数を定期的に呼び出す
1000, // 1000ms(=1秒)に1回定期的に呼び出す
);
}
componentWillUnmount() {
// DOMが削除される時に呼び出される処理
clearInterval(this.timerID); // これ以上tick関数を呼び出さないようにする
}
tick() {
this.setState({
time: this.state.time - 1,
});
if (this.state.time == 0) console.log("カウントダウンが終了しました。");
}
//(中略)
}
// (後略)
行ごとの説明
1度しか呼び出されない(多分)
setInterval(関数オブジェクト, 呼び出す間隔(ミリ秒))
19. 1秒に1回呼び出される関数
ここにカウントダウンの処理を書く
stateに直接代入するのと違い、render()の呼び出しまで自動的にやってくれる つまりstateの値がブラウザ上に反映される
実行するとカウントダウンが始まり、0になった瞬間にメッセージが出力される
https://gyazo.com/112d41faa3fb7a230a3e6c12592f2535
今回は最低限の処理しか書いていないので、0以降も数字が減り続けるぞ
気になった人はソースコードを改変してみよう
余談
code:TypeScriptReact(TSX)
root.render(
<div>
<CountdownTimer time={10} />
<CountdownTimer time={20} />
<CountdownTimer time={8} />
</div>,
);
https://gyazo.com/dcf72e1bf18f2ec863657879ab47728a
それぞれに違う値を渡すことができ、独立して動く
参考
というか、このページの内容はほとんどここから来ている
ここにあった情報を元に、内容を削ったりTypeScriptの型などを追加したりしている