React use在尝试轮询时影响过时的关闭,以及取消对函数的反弹



星期五快乐!我之所以来这里,是因为我的react加密货币项目中出现了一个过时的关闭问题。我有一个函数存储了一个api调用,该调用应该在渲染时运行,之后每6秒运行一次。它还应该在用户停止在输入字段中输入后,每隔500毫秒对同一个api url进行一次调用。

function handleInitPoll(baseAndQuote, side, value) {
getSwapPrice(baseAndQuote, side, value || 0)
.then((res) => {
if (!res.price) {
setIsLoading(true);
} else if (res.error) {
setInputErrorMessage(res.error);
} else if (res.price) {
setIsLoading(false);
setSwapPriceInfo(res);
}
});
}

正如您所看到的,它有3个参数被传递到其中

我在我的onChangeHandler:中取消了它

const debounceOnChange = useCallback(debounce(handleInitPoll, 500, pair, transactionType, fromCurrencyAmount), []);
const handleAssetAmount = (e) => {
const { value } = e.target;
const formattedAmount = handleAssetAmountFormat(value);
setFromCurrencyAmount(formattedAmount);
validateInputAmount(formattedAmount);
debounceOnChange(pair, transactionType, formattedAmount);
};

下面是轮询函数的useEffect:

useEffect(() => {
if (pair && transactionType && symbol === baseAsset) {
handleInitPoll(pair, transactionType, fromCurrencyAmount);
}
const timer = setInterval(handleInitPoll, 6000, pair, transactionType, fromCurrencyAmount);
return () => {
clearInterval(timer);
};
}
}, [pair, transactionType, fromCurrencyAmount, symbol]);

所以这实际上是有效的,因为它使用默认的给定值进行轮询,并从我的api返回响应。使用onChange处理程序从文本字段中输入金额也会填充参数"fromCurrencyMount"。

然而,有一个问题是,退出不起作用。它只是在我停止打字后,在没有500ms的情况下,对每一个按键进行api调用。实际上,每一个按键都会触发一个api调用。但是,如果我从useEffect依赖数组中删除fromCurrencyAmount状态变量,那么去抖动的工作原理是,它对handleInitPoll函数中的api进行去抖动调用,但在发生的下一次轮询中,发送的后续api参数将返回默认值,而不是输入的延续。

我想这是变量被放入依赖数组的副作用。我知道在依赖数组中包含fromCurrencyMount会阻止api调用传递默认参数,但它无法实现去抖动的目的,因为它会对每个onChange事件进行调用。

你知道有什么解决方案吗?感谢您的帮助!

您可以在useEffect中调用debounceOnChange,而不是handleInitPoll:

useEffect(() => {
if (pair && transactionType && symbol === baseAsset) {
debounceOnChange(pair, transactionType, fromCurrencyAmount);
}
const timer = setInterval(handleInitPoll, 6000, pair, transactionType, fromCurrencyAmount);
return () => {
clearInterval(timer);
};
}
}, [pair, transactionType, fromCurrencyAmount, symbol]);

另一种方法是将前三行从useEffect移到onChange事件处理程序中,但仍然需要使用debounceOnChange而不是handleInitPoll。

如果你想在组件第一次渲染时保持初始轮询,你可以将这三行移动到另一个useEffect中,而不依赖于fromCurrenyMamount:

useEffect(() => {
if (pair && transactionType && symbol === baseAsset) {
debounceOnChange(pair, transactionType, fromCurrencyAmount);
}
},[pair,transactionType,symbol]);    

最新更新