You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中useEffect传入的State参数在轮询时未读取问题

问题解决:加密货币应用中防抖/轮询无法读取最新State值

核心问题原因

闭包导致定时器和防抖函数捕获的是组件初始渲染时的State值,后续State更新后,旧的函数引用依然持有旧值,最终引发轮询时参数为undefined的问题。


修复步骤

1. 让API调用函数直接读取最新State(推荐方案)

将handleInitPoll改为直接读取组件内的State,而非通过参数传递,彻底避免闭包捕获旧值:

const handleInitPoll = useCallback(() => {
  getSwapPrice(pair, transactionType, fromCurrencyAmount || 0)
    .then((res) => {
      if (!res.price) {
        setIsLoading(true);
      } else if (res.error) {
        setErrorMessage(res.error);
      } else if (res.price) {
        setIsLoading(false);
        setSwapPriceInfo(res);
      }
    });
}, [pair, transactionType, fromCurrencyAmount]); // State变化时自动更新函数引用

2. 修复useEffect中的轮询逻辑

移除setInterval的参数传递,直接调用更新后的handleInitPoll,同时确保每次State变化时清除旧定时器并创建新实例:

useEffect(() => {
  // 初始立即调用一次
  handleInitPoll();

  // 轮询调用最新的handleInitPoll
  const timer = setInterval(handleInitPoll, 6000);

  // 组件卸载或依赖变化时清除定时器
  return () => clearInterval(timer);
}, [handleInitPoll]); // 依赖改为更新后的函数引用

3. 修复防抖函数的闭包问题

用useCallback包裹防抖函数,确保依赖变化时重新创建防抖实例,调用时无需额外传参:

// 创建防抖函数,依赖handleInitPoll保证引用最新
const debounceOnChange = useCallback(debounce(() => {
  handleInitPoll();
}, 500), [handleInitPoll]);

// 输入变更时直接调用防抖函数
const handleAssetAmount = (e) => {
  const { value } = e.target;
  const formattedAmount = handleAssetAmountFormat(value);
  setFromCurrencyAmount(formattedAmount);
  validateInputAmount(formattedAmount);
  debounceOnChange();
};

替代方案(需保留参数传递时使用)

如果业务必须通过参数传递值,需确保定时器和防抖函数始终获取最新State:

  • 轮询部分:在定时器回调中直接读取当前State,而非初始参数
    useEffect(() => {
      handleInitPoll(pair, transactionType, fromCurrencyAmount);
      const timer = setInterval(() => {
        // 每次调用时读取最新的State值
        handleInitPoll(pair, transactionType, fromCurrencyAmount);
      }, 6000);
      return () => clearInterval(timer);
    }, [pair, transactionType, fromCurrencyAmount]);
    
  • 防抖部分:在useCallback中加入正确依赖,确保防抖函数随State更新
    const debounceOnChange = useCallback(
      debounce((p, t, v) => handleInitPoll(p, t, v), 500),
      [handleInitPoll]
    );
    

内容的提问来源于stack exchange,提问作者Kimbo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 11:01:00