You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React中正确使用debounce实现搜索输入防抖,避免频繁调用接口

React输入框防抖搜索实现方案

问题根源

  1. 前两种写法每次触发逻辑时都会创建全新的防抖函数实例,且创建后没有主动调用返回的防抖函数,导致内部逻辑永远不会执行,防抖规则完全失效。
  2. 第三种写法中useRef保存的防抖函数捕获了初始渲染时的movieSearchString闭包值,后续state更新时函数内部读取的始终是旧值,因此无法输出最新的搜索字符串。

实现代码

import { debounce } from 'lodash'
import { useState, useRef, useEffect } from 'react'

function App() {
  const [movieSearchString, setMovieSearchString] = useState('')
  // 复用同一个防抖函数实例,接收搜索字符串作为入参规避闭包问题
  const debouncedFetch = useRef(debounce((searchStr) => {
    console.log('deb: ' + searchStr)
    const params = {
      apikey: 'somekey'
    }
    if (searchStr.length > 2) {
      params.search = searchStr
      // 此处写实际的API请求逻辑即可
    }
  }, 1000)).current

  const movieInputChangeHandler = string => {
    console.log('onMovieInputChange', string);
    setMovieSearchString(string)
    // 调用防抖函数,传入最新输入值
    debouncedFetch(string)
  }

  // 组件卸载时清理定时器,避免内存泄漏
  useEffect(() => {
    return () => debouncedFetch.cancel()
  }, [debouncedFetch])
  
  const providerValue = {
    moviesList: moviesList,
    movieSearchString: movieSearchString,
  }

  return (
    <MoviesContext.Provider value={providerValue}>
      <div className="App d-flex flex-column px-4 py-2">
        <SearchBar
          onMovieInputChange={movieInputChangeHandler}
        />
        ...Rest of the content
      </div>
    </MoviesContext.Provider>
  );
}

内容的提问来源于stack exchange,提问作者Igal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 09:48:04