😈

[React]入力遅延の共通hooks 〜ライブラリは使用しないぞ〜

2024/12/19に公開

前述

入力遅延の実装を調べてる時にわざわざライブラリを入れる記事しかなかったので 自分のメモのために 記事を作成しました。
特段難しい実装ではありません。

実装

import { useEffect, useState } from "react";

interface UseDebounceProps {
  /** 入力値 */
  value: string;
  /** 遅延時間 */
  delay?: number;
}

interface UseDebounceReturn {
  /** 遅延後の値 */
  debouncedValue: string;
}

export const useDebounce = ({
  value,
  delay = 500,
}: UseDebounceProps): UseDebounceReturn => {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => {
      clearTimeout(timer);
    };
  }, [value, delay]);

  return {
    debouncedValue,
  };
};

上記の実装は、stringの値しか受け付けないので、必要に応じて拡張してください。

使用例

const { debouncedValue } = useDebounce({ value: searchText });

ex.実務での使用例

  • shadcn/ui
  • tanStackQuery

上記の技術を使用していたPJにて、
コンボボックスで検索した文字をリクエストにしてユーザー一覧を取得する実装がありました。

ただ入力されたタイミングでfetchすると、不必要なfetchが増えるので困りますよね?

ここで入力遅延の出番です。
入力遅延し、入力が確定した後にfetchするようにしたことであら不思議、不要なfetchがなくなりました :)

  const [searchText, setSearchText] = useState("");
  const { debouncedValue } = useDebounce({ value: searchText });

  const { isLoading, data } = useQuery({
    queryKey: ["usersSelect", debouncedValue],
    queryFn: async ({ signal }) =>
      await apiClient.users.$get({
        query: { user: debouncedValue },
        config: {
          signal,
        },
      }),
    retry: false,
    enabled: !!debouncedValue,
  });

あとがき

もうほぼ僕の実装メモみたいな感じです。

Discussion