例えばメールアドレス認証を行う際、以下のように一度アプリ画面を離れたのち、再び戻ってくるというフローになる場合が多いです。

  1. ユーザがアプリのフォームにアドレスを入力する。
  2. 入力されたメールアドレスにメールを送信する。
  3. ユーザはメーラーアプリでそのメールを確認する。
  4. その後さきほどまで開いていたアプリに戻ってくる。

上記の最後の部分である、アプリに戻ってきたタイミングで何かしらの処理を走らせたいというニーズがあり、カスタムフックを作成しました。

似たようなニーズをお持ちの方がいればぜひご利用ください。

具体的な挙動ですが、window が一度 blur された(=フォーカスが外れた)のち、再び focus されたときに、引数に渡した callback 関数が動きます。

import { useCallback, useEffect, useRef } from 'react';

type Callback = () => void;

export default function useOnWindowRefocus(callback: Callback): void {
  const isFocusOutOnce = useRef(false);

  const handleFocus = useCallback(() => {
    if (isFocusOutOnce) {
      callback();
    }
  }, [callback]);

  const handleBlur = () => {
    isFocusOutOnce.current = true;
  };

  useEffect(() => {
    window.addEventListener('blur', handleBlur);
    return () => {
      window.removeEventListener('blur', handleBlur);
    };
  }, []);

  useEffect(() => {
    window.addEventListener('focus', handleFocus);
    return () => {
      window.removeEventListener('focus', handleFocus);
    };
  }, [handleFocus]);
}