blog @arfyasu

プログラミングとか趣味のこととか

React でストップウォッチを作ったよ

はじめに

前回のクリックカウンタと起動時間を組み合わせて何か作れないかと考えた所、ストップウォッチを思いついた。
ということで、React でストップウォッチを作ってみました。

ストップウォッチ

デザインやストップウォッチの表記は別として、、、
動きは iOS 標準のストップウォッチに似せたつもりです。

開始や終了については、そんなにハマることなく出来ました。
setIntervel と clearInterval を使うだけです。

それだけだとつまらないとと思ってつけたラップの機能が結構めんどかった。
理由は配列の処理です(はいれつはすきくありません)

躓いたところをメモしておきます。

配列の追加

this.state を使って値を変更する必要があるため、pushメソッドは使用出来ません。
concat メソッドを使って新しい値を追加した配列をセットするようにします。

this.setState({
  values: [newValue].concat(this.state.values)
});
配列の表示

下記のように、mapメソッドを使うコードをよく見かけました。

    var lapList = this.state.lapTimes.map(function(lapTime) {
      return <li>Lap{_this.state.lapTimes.length - i} {_this.getSeconds(lapTime)}</li>;
    });

っが、上記のコードだと、以下の警告が表示されます。

Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `StopWatch`. See https://fb.me/react-warning-keys for more information.

配列やイテレータのようなリストの子要素にはユニークなキーを持つべきだという警告です。

内容と対策については、以下に詳しく載っています。
qiita.com

大事な部分をページ内から引用させて頂くと、

このkeyはVirtualDOMのdiffから実際のDOMに反映させるときに最小限の変更にするために使われます。

とうことです。

下記のようにユニークなキーを指定してあげれば解消します。

var lapList = this.state.lapTimes.map(function(lapTime, i) {
  return <li key={i}>Lap{_this.state.lapTimes.length - i} {_this.getSeconds(lapTime)}</li>;
});
コンストラクタ

最後までよくわからなかったのがコンストラクタで、this.lastLapTime = 0; のように初期化したかったのですが、やり方がわからず断念。
とりあえず以下のコードで逃げたけど、ここだけちょっと嫌な感じです。

if (this.lastLapTime == undefined) {
  this.lastLapTime = 0;
}

まとめ

イベント駆動でゴリゴリ書いてきた、今までのコードより大分すっきりした感じがします。

リセットボタンの処理で値を初期化しただけで、画面がリセットされた時には、すごい気持ちがよかったです。
綺麗に処理が流れると気持ちがいいですね。
これが綺麗なコードかどうかは別としてw

ここ直したほうが良いとかあればご指摘頂けると嬉しいです。

次は親子関係の部分をやってみようと思ってます。

参考

https://www.sitepoint.com/premium/screencasts/building-a-stopwatch-in-react-conditional-rendering