やりたいこと
- カウントダウンしたい時間を
props
へ与えられる - タイマーの進むインターバルを
props
へ与えられる - インターバル毎とカウントダウン終了時にコールバック関数を設定できる
- タイマーロジックとタイマー表示は切り離す
- ロジック部分を担うコンポーネントを作った
- 表示は任意の別のコンポーネントを使えるようにする
他に調べたコンポーネント
- dcousens/react-timers: 公式で非推奨になっているMixinを使ってるのでナシ
- uken/react-countdown-timer: 表示フォーマットを関数で設定するタイプ。実装は参考にした
- StevenIseki/react-timer: 表示は固定フォーマット。タイマーの実装サンプルのような感じ
- troch/react-timer-hoc: HOC(Higher Order Component)による実装。コールバックが無いけど理想に近い。正直コレで良かったけど、作った後に見つけたから仕方ない
実装の方針
-
タイマー機能は公式のタイマーロジック実装を(mixinじゃないかたちで)利用する- この実装を使うとTestがしにくかったので標準関数
setInterval
,clearInterval
を使う
- この実装を使うとTestがしにくかったので標準関数
- タイマーの残り時間は
context
で子コンポーネントへ渡す
作ったもの
今後、npm packageとして公開 したい した。でもまだREADME
を書いてない。
Demo/Usage
noriaki/react-timer-component - Storybook
(なぜかpropType
の一覧表が上手く表示されてないのが気になる)
ミリ秒でカウントダウンする時間remaining
を与え、表示用のコンポーネントを入れ子にして使う。
<Timer remaining={20000}>
<Countdown />
</Timer>
タイマー表示のための子要素<Countdown />
では、context
を読み取れるようにCountdown.contextTypes
を設定する必要がある。サンプルは以下。
const Countdown = (props, context) => {
const d = new Date(context.remaining); // auto passed context.remaining
const { seconds, milliseconds } = {
seconds: d.getUTCSeconds(),
milliseconds: d.getUTCMilliseconds(),
};
return (
<p>{`${seconds}.${milliseconds}`}</p>
);
};
Countdown.contextTypes = {
remaining: PropTypes.number,
};