在反应中使用去抖动搜索输入

using debounce for search input in react

我有一个搜索输入,可以即时进行 API 调用。我想实施去抖动以减少服务器调用量。

  _debouncedSearch() {
    debounce(this.props.fetchRoutes(this.state.searchText), 1000);
  }

  _updateResults(searchText) {
    this.setState({searchText});
    this._debouncedSearch();
  }

我希望每 1 秒 debouncedSearch。但它仍然被即时调用。并抛出错误:

Uncaught TypeError: Expected a function at debounce (lodash.js?3387:10334)

Uncaught Error: A cross-origin error was thrown. React doesn't have access to the actual error object in development.

我觉得这个问题肯定被问过很多次,但 none 的解决方案似乎对我有用。有人可以向我解释这里到底是什么问题吗?我以为 debounce 只是一个 setTimeOut。

谢谢

_.debounce 已经是一个执行函数(function returns function)。然后 _debouncedSearch 应该是 class 的属性,而不是方法:

  _debouncedSearch=  debounce(() => this.props.fetchRoutes(this.state.searchText), 1000);

而不是:

  _debouncedSearch() {
    debounce(this.props.fetchRoutes(this.state.searchText), 1000);
  }

此外,请注意,_.debounce 的第一个参数是一个函数 (() => this.props.fetchRoutes...),而不是直接 this.props.fetchRoutes...

constructor(props) {
    super(props);
    this.state = {
      searchText: '',
    };
    this._debouncedSearch = debounce(
      () => this.props.fetchRoutes(this.state.searchText),
      1000
    );
  }

  _updateResults(searchText) {
    this.setState({searchText});
    this._debouncedSearch();
  }

这是完整的工作代码,以备不时之需!

最近发现这个问题很有帮助。这是我的优化解决方案:

const [searchTerm, setSearchTerm] = useState("");
const [result, setResult] = useState([]);

async function fetchData(searchTerm: string) {
  const { data } = await client.query(searchTerm);
  setResult(data);
}

const debounceLoadData = useMemo(() => debounce(fetchData, 700), []);

useEffect(() => {
  window.addEventListener("keydown", debounceLoadData(searchTerm));
  return () => {
    window.removeEventListener("keydown", debounceLoadData(searchTerm));
  };
}, [searchTerm]);

这只会在用户停止输入 700 毫秒后调用一次 fetchData() 函数。然后我使用 useMemo 来缓存每个结果。如果用户多次搜索相同的值,它将 return 缓存的值并且不会调用 fetchData() 函数超过必要。