9

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

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

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

我期待debouncedSearch每1秒。但它仍然是即时调用的。并抛出错误:

未捕获的类型错误:在去抖动时需要一个函数 (lodash.js?3387:10334)

未捕获的错误:引发了跨域错误。React 无法访问开发中的实际错误对象。

我觉得这个问题必须被问到很多,但似乎没有一个解决方案对我有用。有人可以向我解释这里到底是什么问题吗?我认为去抖动只是一个 setTimeOut。

谢谢

4

3 回答 3

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

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

这是完整的代码,以防有人需要它!

于 2017-12-01T18:58:20.763 回答
4

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

  _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...

于 2017-12-01T18:45:42.057 回答
0

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

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]);

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

于 2021-11-25T02:39:20.097 回答