カテゴリ: React 更新日: 2025/12/11

Reactのカスタムフックでタイマー・カウントダウンを管理する方法!初心者でもわかるReact Hooks入門

カスタムフックでタイマー・カウントダウンを管理する方法
カスタムフックでタイマー・カウントダウンを管理する方法

先生と生徒の会話形式で理解しよう

生徒

「Reactでタイマーやカウントダウンを作りたいです。でも同じ処理を何度も書くのは大変です。」

先生

「その場合は『カスタムフック』を作ると便利です。処理を一箇所にまとめて再利用できます。」

生徒

「カスタムフックなら、タイマーの開始や停止も簡単に管理できるんですか?」

先生

「はい、では実際にどのように作るか見ていきましょう。」

1. タイマーをカスタムフックで管理するメリット

1. タイマーをカスタムフックで管理するメリット
1. タイマーをカスタムフックで管理するメリット

Reactではタイマーやカウントダウンを管理する場合、setIntervalsetTimeoutを使います。これをコンポーネントごとに書くと、同じ処理が複数箇所に重複してしまいます。
カスタムフックを作ると、タイマー処理を一箇所にまとめ、どのコンポーネントからも呼び出せるようになります。

例えば、ゲームのカウントダウンや通知のタイマーなど、再利用したい場面でとても便利です。

2. タイマー用のカスタムフックを作る

2. タイマー用のカスタムフックを作る
2. タイマー用のカスタムフックを作る

まず、タイマーやカウントダウンを管理するカスタムフックを作ります。


import { useState, useEffect, useRef } from "react";

function useTimer(initialSeconds) {
  const [seconds, setSeconds] = useState(initialSeconds);
  const [isActive, setIsActive] = useState(false);
  const intervalRef = useRef(null);

  const start = () => setIsActive(true);
  const pause = () => setIsActive(false);
  const reset = () => setSeconds(initialSeconds);

  useEffect(() => {
    if (isActive) {
      intervalRef.current = setInterval(() => {
        setSeconds(prev => {
          if (prev <= 0) {
            clearInterval(intervalRef.current);
            return 0;
          }
          return prev - 1;
        });
      }, 1000);
    } else {
      clearInterval(intervalRef.current);
    }

    return () => clearInterval(intervalRef.current);
  }, [isActive]);

  return { seconds, isActive, start, pause, reset };
}

export default useTimer;

このフックでは、タイマーの残り時間をsecondsで管理し、startで開始、pauseで停止、resetで初期値に戻せます。
useRefを使うことで、コンポーネントが再レンダリングされても同じタイマーIDを保持できます。

3. カスタムフックを使ったコンポーネント例

3. カスタムフックを使ったコンポーネント例
3. カスタムフックを使ったコンポーネント例

次に、先ほど作ったuseTimerを使ってカウントダウンを表示する例です。


import React from "react";
import useTimer from "./useTimer";

function Countdown() {
  const { seconds, isActive, start, pause, reset } = useTimer(10);

  return (
    <div>
      <h1>残り時間: {seconds}秒</h1>
      <button onClick={start}>スタート</button>
      <button onClick={pause}>一時停止</button>
      <button onClick={reset}>リセット</button>
    </div>
  );
}

export default Countdown;
(画面に「残り時間: 10秒」と表示され、スタートボタンを押すと1秒ごとに減っていきます。一時停止やリセットも可能です)

カスタムフックを使うことで、タイマーの状態管理やボタン操作のロジックがコンポーネントから分離され、コードがすっきりします。

4. カスタムフックの応用例

4. カスタムフックの応用例
4. カスタムフックの応用例

このカスタムフックは、単純なカウントダウンだけでなく、複数のタイマーやゲームの残り時間、アンケートの制限時間などにも応用できます。
さらに、タイマーが0になったときにイベントを発火させる処理を追加すると、通知やアラートにも活用できます。


useEffect(() => {
  if (seconds === 0) {
    alert("時間切れです!");
  }
}, [seconds]);

このように、カスタムフックを活用するとタイマー関連の処理を一箇所にまとめて、再利用性の高いコードを書くことができます。

5. ポイント整理

5. ポイント整理
5. ポイント整理

Reactでタイマーやカウントダウンを作る場合、useStateuseEffectを使うのが基本です。
カスタムフックにまとめることで、コンポーネントがシンプルになり、処理を再利用できるので開発効率が上がります。
タイマーの開始・停止・リセットの操作や、0秒になったときの処理もカスタムフックに含めることができます。

まとめ

まとめ
まとめ

Reactでタイマーやカウントダウンを管理する方法を学んできましたが、あらためて振り返ってみると、カスタムフックという仕組みがいかに便利で強力であるかがよくわかります。タイマーやカウントダウンは、ゲームや学習アプリ、タスク管理ツールなど、多くのアプリケーションに欠かせない要素です。しかし、そのたびに毎回同じような処理を書いていては、コードは複雑になり、管理が難しくなってしまいます。カスタムフックを使えば、複雑なロジックを一箇所にまとめ、何度でも再利用できる美しい仕組みが作れます。

また、今回の解説を通じて、useStateで状態を管理し、useEffectで時間の経過を監視し、useRefでタイマーIDを保持するという、React Hooksの基本的な役割を自然に理解できたはずです。特に、コンポーネントが再描画されても変わらない値を保持できるuseRefの特性は、タイマー処理との相性がよく、初心者でも扱いやすいポイントです。こうしたReact Hooksの特徴を体験していくと、実際の開発でも困らずに複雑な動きを管理できるようになります。

さらに、タイマーが0になったときのイベント処理や、複数のタイマーを同時に管理するなど、さまざまな応用例も紹介しました。これにより、単なるカウントダウン機能にとどまらず、アプリ全体に広がる動的な動きを作り出す基盤が整います。カスタムフックを使った開発は、コードの重複を減らし、アプリケーションの見通しを良くし、メンテナンス性を高める大きな効果があります。

理解を深めるミニサンプル:カスタムフックで簡単リピートタイマー

最後に、今回学んだ内容をさらに深めるため、一定時間ごとにメッセージを更新する簡単なタイマーのサンプルを紹介します。カスタムフックを使えば、タイマーが止まったり再開したりする動きを柔軟に扱えます。


import { useState, useEffect, useRef } from "react";

function useRepeatTimer(interval) {
  const [count, setCount] = useState(0);
  const [running, setRunning] = useState(false);
  const timerRef = useRef(null);

  const start = () => setRunning(true);
  const stop = () => setRunning(false);

  useEffect(() => {
    if (running) {
      timerRef.current = setInterval(() => {
        setCount(prev => prev + 1);
      }, interval);
    } else {
      clearInterval(timerRef.current);
    }

    return () => clearInterval(timerRef.current);
  }, [running]);

  return { count, start, stop };
}

このミニサンプルは、一定間隔でカウントが増えていくタイマーを表しています。React Hooksの動きがより直感的に理解でき、実際のアプリケーションに取り入れやすい構造になっています。学んだ内容をそのまま活用できるので、ぜひ試してみてください。

先生と生徒の振り返り会話

生徒

「先生、タイマーのしくみがすごくよくわかりました!カスタムフックってこんなに便利なんですね。」

先生

「そうなんです。繰り返し使う処理はカスタムフックにまとめると、とても管理しやすくなります。今回のタイマーはその良い例ですね。」

生徒

「たしかに、start・pause・resetを一つのファイルにまとめるだけで、コンポーネントのコードがスッキリして読みやすくなりました!」

先生

「その通り。コードの再利用性が高くなると、開発が楽になるだけでなく、バグも減ります。ReactのHooksはこうした管理を得意としています。」

生徒

「これならゲームの制限時間やクイズの制限時間、通知のタイマーも作れそうです!」

先生

「もちろん作れますよ。ぜひ今回のカスタムフックを基礎にして、実践的なアプリも作ってみましょう。」

生徒

「はい!Reactでできることがどんどん増えてきて楽しいです!」

カテゴリの一覧へ
新着記事
New1
React
Reactコンポーネントの再利用と分割を完全マスター!初心者でもわかるコンポーネント設計
New2
React
ReactでAxiosインターセプターの使い方を完全ガイド!初心者でもわかるリクエストとレスポンスの処理方法
New3
React
JSXの書き方!初心者でもわかるReactタグと属性の基本ルール解説
New4
React
ReactとDockerを使った開発環境構築の基本を徹底解説!初心者でもわかるReactとDockerの連携方法
人気記事
No.1
Java&Spring記事人気No1
React
ReactでonChangeイベントを使ってフォーム入力値を管理する方法を初心者向けに解説
No.2
Java&Spring記事人気No2
React
ReactとTypeScriptの環境構築をやさしく解説!Viteとtsconfigの設定も丁寧に紹介
No.3
Java&Spring記事人気No3
React
Reactのイベントハンドリングのアンチパターンまとめ!初心者でもわかる注意点
No.4
Java&Spring記事人気No4
React
Reactのカスタムフックの作り方を完全ガイド!再利用可能なロジックを切り出す仕組み
No.5
Java&Spring記事人気No5
React
ReactでFetch APIのローディング状態を管理する方法|初心者にもわかる解説
No.6
Java&Spring記事人気No6
React
create-react-appでReactプロジェクトを作成する手順を初心者向けに完全解説!
No.7
Java&Spring記事人気No7
React
ReactのuseStateとuseEffectでよくあるエラーと解決方法ガイド!初心者でもわかるReactフック
No.8
Java&Spring記事人気No8
React
Reactのフォーム処理でよくあるエラーと解決法を完全解説!初心者でも安心して学べるReact入門