🎮

【React / useHooks】開発不要で使える便利なカスタムフックス20選

2023/09/02に公開

フロントエンドで処理をカスタムフックス化する際、windowの高さを取得するなど、どのプロジェクトでもある程度決まったコードがありますよね。

useHooksはそういったカスタムフックスのライブラリとなっています。カスタムフックは自前で作ってしまうことが多いものの部分的に任せられるかなと思い、useHooksに登録されている便利そうなカスタムフックスをピックアップしてみました。

useHooksを使うにあたって

  • カスタムフックスは自前で用意する方がカスタマイズ性高く安心して使える
  • 調べれば同じ機能を持つカスタムフックのコードが出てくるので必ずしもuseHooksを使う必要はない
  • プロトタイプ開発とかで速度が求められるなら導入するのはありかも
  • 最初からこういうのに慣れすぎると開発理解があやふやになるのではといった議論はありそう
  • こういうカスタムフック置くと便利だなという確認にも良さそう

結論、プロジェクトに入れるかどうかは保留ですが、スピード重視でなるべく開発する量を減らしたいなら入れる価値はあるなと感じました。

useHooksの便利なカスタムフックス一覧

useLocalStorage

/** drawingをローカルストレージに保存する */
const [drawing, saveDrawing] = useLocalStorage("drawing", null);

ローカルストレージを扱う際、デフォルトの記述だと保存や呼び出しが若干面倒だし管理が分散してしまったいりますが、useLocalStorageを用意してもう一個ローカルストレージ用の変数をまとめたフックを用意すれば便利そうだなと思いました。

普段は、zustandなどの状態管理ライブラリにあるローカルストレージ機能を使って変数を出し入れしてるものの、useLocalStorageの方がシンプルに管理できるかもなので使おうか検討してみます。

useEventListener

/** クリックを検知して処理を実行する */
useEventListener(document, "mousedown", handleClick);

要素の変更などを監視するイベントリスナーを設定できます。記述がシンプルで分かりやすいのが良いですね。

useFetch

// ** ポケモンのデータを取得する */
const { error, data } = useFetch(
  `https://pokeapi.co/api/v2/pokemon/${count}`
);

ゼロからデータをfetchする時にちょっと楽になりそうなカスタムフックです。第二引数にoptionsで認証やメソッドを設定できるのと、キャッシングもしているようで最低限の表示最適化をしてくれます。

useList

const [list, { set, push, removeAt, insertAt, updateAt, clear }] = useList([
  "First",
  "Second",
  "Third",
]);

リストを操作するのに基本的な処理が書かれているのは便利ですね。これだけだと不十分かもですが、操作する予定のある配列をuseListで設定して不足している機能を書き足すみたいな形でも良いかも。

useHover

/** 要素がホバーされたかどうかを判定する */
const [ref, hovering] = useHover();

要素のホバーを検知するカスタムフックです。ホバーに対してスタイルを変えたい場合の他にも実用的に使えそうなケースはあると思うので、活用できるかも。

useCopyToClipboard

/** クリップボードにコピーする */
const [copiedText, copyToClipboard] = useCopyToClipboard();

値をクリップボードにコピーする関するです。ブラウザの互換性を考慮されているようで、それらが考慮されていないのであればこのカスタムフックを使うと動作が安定するかもしれません。

useLongPress

const attrs = useLongPress(
  () => {
    setIsOpen(true);
  },
  {
    onStart: (event) => console.log("Press started"),
    onFinish: (event) => console.log("Press Finished"),
    onCancel: (event) => console.log("Press cancelled"),
    threshold: 500,
  }
);

ロングプレスを検知して処理を走らせることができます。onStartなども整備されてるのが嬉しいですね。

useKeyPress

/** 右矢印が押された場合に処理を実行する */
useKeyPress("ArrowRight", onKeyPress);

keyPressの値を検知して処理を簡単に実行することができます。options.targetを設定することで影響範囲を調整することも可能です。

useScript

/** 読み込みが完了するとstatusに"ready"が返ってくる */
const status = useScript(
  `https://cdnjs.cloudflare.com/ajax/libs/mootools/1.6.0/mootools-core.js`,
  {
    removeOnUnmount: false,
  }
);

コンポーネント単位で外部スクリプトを取得して表示をコントロールする時に役立ちそうです。

useInterval

const clear = useInterval(() => {
  setIndex(index + 1);
}, 1000);

処理を実行する間隔を簡単に設定することができます。以前。setIntervalを使おうとしたもののなぜか思ったように実行されない場合があったので、カスタムフックにして処理したら良い感じになるのかなぁと期待してます。

useWindowSize

/** ウィンドウサイズを取得する */
const { width, height } = useWindowSize();

ウィンドウサイズを取得することはよくあるのでカスタムフックにして持っておきたいですね。

useMeasure

/** 指定した要素のサイズを取得する */
const [ref, { width, height }] = useMeasure();

指定した要素のサイズを取得するのはuseMeasureです。何も考えずに使えそうで良い笑

useWindowScroll

const [{ x, y }, scrollTo] = useWindowScroll();

スクロール位置の取得と、scrollToでスムーススクロールさせることができます。

useClickAway

/** 要素の外側がクリックされた時、モーダルを閉じる */
const ref = useClickAway(() => {
  setIsOpen(false);
});

要素の外側をクリックしたことを検知するカスタムフックです。ちょっとしたモーダルなどで要素の外側がクリックされたかどうかを判定するのが楽になりそうです。

usePrevious

/** 直前のcolorを保持する */
const previousColor = usePrevious(color);

usePreviousで直前のデータを保持しておくことができます。地味に便利ですね。

useMouse

/** マウスのカーソル位置を取得 */
const [mouse, ref] = useMouse();

マウスのカーソル位置を取得することができます。refを設定することで要素に対する相対位置も取得できて便利そう。

useDefault

const initialState = { name: "Tyler" };
const defaultState = { name: "Ben" };
/** デフォルト値を設定 */
const [user, setUser] = useDefault(initialState, defaultState);

useState()の要領でデフォルト値を保存しておくことができます。値が存在しない場合、デフォルト値が表示される形になります。(初期値ではなく、setUser(undefined)等で変更後でも同様)

useNetworkState

/** ユーザーのネットワーク状態を取得する */
const { online } = useNetworkState();

ユーザーのネットワーク状態を取得するフックスです。簡単に取得はできるものの、どこかで使う機会あるかなと思いました。

useContinuousRetry

const hasResolved = useContinuousRetry(() => {
  console.log("retrying");
  return count > 10;
}, 1000);

再試行処理を行う処理を簡単に記述できます。インターバルはもちろん、optionsのmaxRetriesで最大試行回数を設定することもできます。

useRenderCount

/** コンポーネントのレンダリングを監視する */
const renderCount = useRenderCount();

コンポーネントがレンダリングされた回数を取得することで、パフォーマンス向上に役立てることができます。useRenderInfoを使うとより詳細な情報を取得できます。

まとめ

便利なカスタムフックスが多いなど関心しました。ほとんどは独自に実装することも容易であるものの、結果は同じになるはずです。

使うかどうかは個人開発であれば検討する予定で、実務ではフックスを外部ライブラリに依存するのはどうかといった話もあるので微妙だなと。

とはいえ、useHooksを入れておけば管理するファイル数を削減できるメリットはあると思っていて、活用範囲を少し模索してみようと思いました。

フロントエンド通信

Discussion