【问题标题】:How to debounce Lodash call to fetch in Typescript properly?如何去抖动 Lodash 调用以正确获取 Typescript?
【发布时间】:2020-07-05 10:36:18
【问题描述】:

我对 React 和 Typescript/JS 比较陌生,我正在尝试了解如何正确地对 Promise 的调用进行去抖动。有一个按钮可以增加/减少所需的购买数量,并且只有在一段时间后我才想实际执行对后端 API 的调用,以避免用户只是重复点击 +/- 按钮并向服务器发送垃圾邮件。

import debounce from 'lodash/debounce'

const [isQueryingPrice, setIsQueryingPrice] = useState(false);
const [desiredPurchaseQty, setDesiredPurchaseQty] = useState<number>(1);

const changeQty = (delta: number) => {
    setDesiredPurchaseQty(desiredPurchaseQty + delta);
    setIsQueryingPrice(true);
    debounce(fetchPrice, 1000)();

}
const incrementQty = (event: any) => {
    changeQty(1);
}
const decrementQty = (event: any) => {
    changeQty(-1);
}

const fetchPrice = (qty: number) => {
    // not sure that arrow function wrapping fetch is the best approach here?
    // some imaginary api
    fetch("https://api.example.com/get-price?qty=" + qty).then((response) => {
        return response.json();
    });

}

// in my component:
< div>
    <Button onClick={decrementQty}>Dec</Button>
    <Button onClick={incrementQty}>Inc</Button>
</div>

但是,虽然递增/递减有效,但当定时器到期时,去抖动函数会被多次触发。我希望在用户停止按下更改数量按钮时执行一个承诺,并且我希望承诺执行尊重计数,即如果用户按下计数按钮 3 次,总数为 4,那么电话获取价格应该是 4 的数量。

我认为这可能是更改状态的调用会导致重新渲染和创建新的去抖动函数,并且我认为对去抖动函数的调用可能不会导致旧的预定回调被清除。然而,这就是我对 JS 的了解开始崩溃的地方......

我还想知道该方法在初始加载价格时应该如何工作:我认为在 useEffect() 内部有一个调用来获取页面首次加载时的价格。

【问题讨论】:

  • 你能在沙箱中做一个可重现的例子吗? codesandbox。目前尚不清楚您期望什么行为。

标签: javascript reactjs typescript lodash


【解决方案1】:

您不想在每次更改数量时都创建一个新的去抖动函数,当然也不是在每次渲染时。

在这里,我用 debounce 函数包装了原始 fetchPrice,并保存了状态,因此我们可以在渲染中使用相同的 debounced 函数。

const [debouncedFetchPrice] = useState(() =&gt; debounce(fetchPrice, 1000));

然后在changeQty 函数中你应该调用debouncedFetchPrice 而不是fetchPrice

这应该意味着它将在 1000 毫秒延迟后以最新的 desiredPurchaseQty 值触发。

还有……

我发现这篇文章过去对使用 useEffect 创建 useDebounce 挂钩很有用。看看这个 https://dev.to/gabe_ragland/debouncing-with-react-hooks-jci

【讨论】:

  • 我发现这解决了多次按钮按下重复查询的问题,但执行的查询似乎没有使用更新的状态,它只使用第一个查询的状态(即changeQty() 中的更改不受尊重)。请问有什么想法吗?
  • 你打电话给debouncedFetchPrice(desiredPurchaseQty)了吗?请使用codesandbox... 举例说明,即使您必须使用超时或其他方式模拟 api 调用。
  • 经过大量研究如何进行去抖动,我能够理解您的解释。谢谢。
猜你喜欢
  • 2021-07-16
  • 2015-05-21
  • 2017-05-03
  • 2019-01-21
  • 2016-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多