4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React Hook Timer】ポモドーロタイマーを作った時、onExpireで死ぬほどハマった話

Last updated at Posted at 2025-03-03

はじめに

よくあるカウントダウンタイマーをReact Hook Timerを使って
作ってみた時に、onExpireでハマりました

問題

ドキュメントによるとonExpireはコールバック関数
つまり、カウントダウンが終わった後に呼び出される関数ということらしい

ポモドーロタイマーなので、Timeが終わった後、breakTimeが自動で再生されるように、
下記のように書いたところ、

  const { seconds, minutes, hours, isRunning, start, pause, resume, restart } = useTimer({
    expiryTimestamp: getExpiryTimestamp(getDuration()),
    autoStart: false,
    onExpire: () => {
      if (mode === "work") {
        setMode("break");
        restart(getExpiryTimestamp(breakTime), true);
      } else {
        setMode("work");
        restart(getExpiryTimestamp(time), true);
      }
    },
  });

死ぬほどバグる、、、
何でやねん、、、
バグらなかった状況としてはユーザー側が、休憩のスタートボタンを押下するなどのアクションを追加した時だけでした。
ただ、これだと要件が合わないので、一旦無視してuseEffectでやることにしました

解決方法

実際のコードはこちら

  const { seconds, minutes, hours, isRunning, start, pause, resume, restart } = useTimer({
    expiryTimestamp: getExpiryTimestamp(getDuration()),
    autoStart: false,
    onExpire: () => {
      if (mode === "work") {
        setMode("break");
      } else {
        setMode("work");
      }
    },
  });

  useEffect(() => {
    if (firstRender) {
      setFirstRender(false);
      return;
    }
    if (mode === "work") {
      restart(getExpiryTimestamp(time), true);
      console.log(mode);
    } else {
      restart(getExpiryTimestamp(breakTime), true);
      setStop(true);
      console.log(mode);
    }
  }, [mode]);

ただ、useEffectを使用するとonExpireが原因で、modeが切り替わりまくって、
レンダリングが繰り返されてしまうので、firstRenderをつけます
最初のレンダリング時には何もしないでただreturnするっていう条件をつけてあげるだけのフラグです

おわりに

作るものが特殊なせいなのかreact-hook-timerはめちゃめちゃ使いづらかった
多分、ポモドーロタイマーには合わないんだろうなと思ったので、
どこかで自作のタイマーを作った方が早そうな気がしました。
現状は困っていないのでリファクタリングしながらやってみます

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?