UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【React】debounce機能の実装

ユーザーが入力したテキストで検索してサジェストするようなコンポーネントをつくりたい

以前、1文字ずつ入力するたびにリクエストを送ってしまうことの対処法はAbortControllerを使えばよいことがわかったので、あとは実際にどういう風にコンポーネントを作るかを考える

uga-box.hatenablog.com

入力したら次から次へとリクエストするのではなく、ユーザーの入力後の1秒後にその時入力されている文字でリクエストするようにしたい

これをdebounce機能ということを知った

zenn.dev

上の記事とちょっと違うのは、1秒後の実行中にもしまた入力が始まればリクエストを中断し、また1秒待つということがやりたい

これを満たす実装をAbortControllersetTimeoutを駆使して考えてみたのが以下

  const handleChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
    if (controller) {
      controller.abort();  // useStateで管理しているAbortControllerインスタンスがあればabortする
    }
    const _controller = new AbortController();  // 以前のAbortControllerは使えないので新しいインスタンスを作成
    setController(_controller);
    const text = event.currentTarget.value;
    setInputValue(text);  // 入力された値は遅延なしで表示させる
    if (text.length >= 1) {
      setIsLoading(true);  // ローディング中
      if (timer) {
        clearTimeout(timer);  // setTimeoutで待機中であれば前回のものは破棄
      }
      setTimer(
        setTimeout(() => {
          searchSuggest(_controller, text);  // 1秒後に入力された文字列で検索
        }, 1000),
      );
    } else {
      // 全て消した時の処理
    }
  };

これで一応やりたいことができた