React.jsでタイムアラームを作ってみた

現在React.jsを勉強中でして、今回はこのような物を作成しました。

タイムアラームです。
サービスはFirebaseでホスティングしました。→URL(https://easy-alarm-cf7a0.web.app/)

ソースコードはindex.htmlだた一枚(cssや音声ファイルは別ですが)。

リポジトリはこちら(https://github.com/smithshiro/easy-alarm)

React.jsのコンポーネントの組み合わせとCSSで時計の描画のみを使って作りました。

コンポーネントを分解

画面の要素は以下のようにコンポーネントとしてまとめました。

  • 時計コンポーネント(Clock):時刻情報を管理して、時計盤やアラームに渡す役割
  • 時計盤コンポーネント(ClockRound):時計盤を描画する役割
  • 時針コンポーネント(HourHand):時針を描画する役割
  • 分針コンポーネント(MinuteHand):分針を描画する役割
  • 秒針コンポーネント(SecondHand):秒針を描画する役割
  • アラームコンポーネント(Alarm):アラームを設定する役割

Clockコンポーネント

componentDidMount内のsetIntervalで1秒おきに時刻を更新

ステートの更新はsetStateで行います。

更新した時刻のステート(hour,minute,second)はClockRoundAlarmのプロパティとして渡しています。

ClockRoundコンポーネント

時刻のメモリの位置を計算して描画

時計盤の時刻のメモリの部分は三角関数で位置を調整して描画しました。

makeMemoryStyleでその計算を行っています。

Clockコンポーネントの時刻の更新に合わせて針を動かす

ClockコンポーネントのstateをClockRoundコンポーネント経由でそれぞれの針のコンポーネントであるHourHand,MinuteHand.SecondHandのpropsに渡しています。

それぞれのコンポーネントではpropsが更新されたタイミングでrender関数が実行され、再度新しい時刻の値を元に針の座標が更新されます。

こうして、時刻通りに時計の針が動くようにしています。

設定した時刻通になるとアラームをあげるAlarmコンポーネント

最後に設定した時刻になればアラームをあげる(PCで見れば音がでます)Alarmコンポーネントについて説明します。

Alarmコンポーネントでは以下の操作に対してアクション用の関数を定義しています。

  • アラームにする時刻を設定:changeAlarmTime
  • アラームを設定:setAlarm
  • アラーム設定を解除:clearAlarm
  • アラーム状態を解除:stopAlarm

changeAlarmTimeではフォームの入力値をstateに更新しています。

setAlarmではenableAlarm(アラーム状態の有効フラグ)をONにして、1秒おきに現在時刻がアラーム時刻になっているかのチェックをsetIntervalで行うようにします。

setInterval内の処理でアラーム時刻になった場合、背景を赤にして音声を流すようになっています。

clearAlarmではsetAlarmで設定したタイマーをリセットしており、

stopAlarmではアラームが流れた時に音声を停止した後にclearAlarmを実行しています。

このような感じで、フォーム1つとボタン1つでタイマーの制御を行いました。

学んだこと

stateは極力、第一階層までのオブジェクトを格納すること

setStateでstateを更新する時、ネスト構造のオブジェクトを更新が簡単ではなかったため

stateはネストが深くならないように設計したいものです。

親から引き継いだpropsをstateに入れてはならない

Clockコンポーネントの時刻のstateをHourHandコンポーネントに渡してスタイルをpropsで引き継いだ値をstateに入れて更新しようとしたら、無限ループに陥ってしまいました。

propsの値はstateにしてはいけない。

UIの部品ごとにコンポーネントは分けた方が後から改修がしやすい←当たり前か

最初は前要素を一つのコンポーネントにして動かしていましたが、後からスタイルを微修正する時に

ソースコードでそれを修正する箇所が分かりづらかったので、UIのパーツごとにクラスを作り

それを組み合わせるようにすれば改修がしやすいです。

以上、React.jsを使えばタイマーアプリもオブジェクト指向で後から修正がしやすいように実装ができるという会でした。

 

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です