Lodash debounce 在另一个函数中调用时不起作用

问题描述 投票:0回答:1

我在 React 应用程序中使用 lodash debounce 函数,但我似乎无法让它按预期工作。当我尝试对整个函数进行去抖处理时,它可以正常工作,但是当我在另一个函数中调用去抖函数时,会导致对去抖函数的每次调用都运行,而不是仅运行最后一个函数。

这是我的整个功能:

const handleSearchChange = (query: string) => {
    setSearchQuery(query)
    if (!query.replace(/\W/gi, '')) {
      setSearchResults([])
      return
    }

    if (googleAPI) {
      fetchGooglePredictions(query)
    } else {
      fetchMapboxPrediction(query)
    }
  }

当我对整个函数调用 debounce 时,它会按预期工作。然而,这被称为输入的 onChange,并且对整个事物进行去抖会导致输入更改也去抖。我要做的只是对代码的第二个 if 条件进行反跳,如下:

 const getPredictions = (query: string) => {
    if (googleAPI) {
      fetchGooglePredictions(query)
    } else {
      fetchMapboxPrediction(query)
    }
  }

  const debounceSearchPredictions = debounce(getPredictions, DEBOUNCE_TIMEOUT)

  const handleSearchChange = (query: string) => {
    setSearchQuery(query)
    if (!query.replace(/\W/gi, '')) {
      setSearchResults([])
      return
    }

    debounceSearchPredictions(query)
  }

但是现在,getPredictions 的每个调用都会在 DEBOUNCE_TIMEOUT 之后运行,而不仅仅是最后一个调用。以前的人不会提前返回。作为参考, getPredictions 中的两个函数都是异步的;这可能是导致这种行为的原因吗?我也尝试过使用 useCallback 作为 debounce 函数(lodash debounce not debounce in React),但没有运气。

reactjs async-await lodash debouncing
1个回答
0
投票
const debounceSearchPredictions = debounce(getPredictions, DEBOUNCE_TIMEOUT)

当您运行此行时,您将创建一个全新的函数。该函数有一个内部计时器,如果多次调用,该计时器将重置。但每次重新运行这行代码时,您都会创建一个不同的函数,并具有自己的独立计时器。因此,您会遇到这样的情况:您不断创建更多函数,每个函数仅被调用一次。

相反,您只需调用

debounce
一次,然后多次调用结果函数。例如:

// Outside the component, so it only happens once
const getPredictions = (query: string) => {
  if (googleAPI) {
    fetchGooglePredictions(query)
  } else {
    fetchMapboxPrediction(query)
  }
}
const debounceSearchPrediction = debounce(getPredictions, DEBOUNCE_TIMEOUT)

// Inside the component, since it needs to refer to `setSearchQuery`
const handleSearchChange = (query: string) => {
  setSearchQuery(query)
  if (!query.replace(/\W/gi, '')) {
    setSearchResults([])
    return
  }

  debounceSearchPredictions(query)
}

如果你无法将

getPredictions
移到组件之外,因为它依赖于组件内部的某些其他值,那么你可以将其保留在组件内部,但使用 React 的记忆工具仅创建一次:

// Inside the component
const debounceSearchPrediction = useMemo(() => {
  const getPredictions = (query: string) => {
    if (googleAPI) {
      fetchGooglePredictions(query)
    } else {
      fetchMapboxPrediction(query)
    }
  }
  return debounce(getPredictions, DEBOUNCE_TIMEOUT)
}, []); // <--- add dependencies, if any
© www.soinside.com 2019 - 2024. All rights reserved.