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

React中如何限制dispatch通知函数每5秒仅可调用一次

解决React通知5秒内仅触发一次的问题

问题场景

开发React应用时,服务器返回操作结果(如登录错误/成功)会触发通知,但重复点击操作按钮时通知频繁弹出,需要限制通知每5秒最多触发一次。

原尝试代码的问题

你之前的实现存在两个核心问题:

  1. setTimeout在组件每次渲染时都会执行,而非调用通知后才启动,导致状态重置逻辑混乱;
  2. 返回isCallable && func的方式错误,当isCallable为false时会返回布尔值,调用时会抛出"not a function"错误。

正确实现方案

以下是两种可靠的实现方式,任选其一即可:

方案一:使用useRef记录触发时间戳

通过记录最后一次触发通知的时间,用时间差判断是否允许触发:

import { useContext, useRef } from 'react';
import { v4 } from 'uuid';
import { NotificationContext } from './NotificationProvider';

export const useAddNotification = () => {
  const dispatch = useContext(NotificationContext);
  // 存储最后一次触发通知的时间戳
  const lastTriggered = useRef(Date.now());
  const COOLDOWN_DURATION = 5000; // 5秒冷却时长

  return (props) => {
    const now = Date.now();
    // 判断是否超过冷却时间
    if (now - lastTriggered.current >= COOLDOWN_DURATION) {
      dispatch({
        type: "ADD_NOTIFICATION",
        payload: {
          id: v4(),
          ...props
        }
      });
      lastTriggered.current = now; // 更新最后触发时间
    }
  };
};

方案二:使用useState+useEffect管理可调用状态

通过状态控制触发权限,同时确保定时器正确清理避免内存泄漏:

import { useContext, useState, useEffect, useCallback } from 'react';
import { v4 } from 'uuid';
import { NotificationContext } from './NotificationProvider';

export const useAddNotification = () => {
  const dispatch = useContext(NotificationContext);
  const [isAllowed, setIsAllowed] = useState(true);
  const COOLDOWN_DURATION = 5000;

  const triggerNotification = useCallback((props) => {
    if (!isAllowed) return;
    
    dispatch({
      type: "ADD_NOTIFICATION",
      payload: {
        id: v4(),
        ...props
      }
    });
    setIsAllowed(false);
  }, [dispatch, isAllowed]);

  // 当触发后启动定时器,到期恢复可调用状态
  useEffect(() => {
    let timer;
    if (!isAllowed) {
      timer = setTimeout(() => {
        setIsAllowed(true);
      }, COOLDOWN_DURATION);
    }
    // 组件卸载或状态变更时清理定时器
    return () => clearTimeout(timer);
  }, [isAllowed]);

  return triggerNotification;
};

使用说明

修改后,App.js中的调用方式保持不变:

const dispatchAddNotification = useAddNotification();

// 登录逻辑中正常调用即可
dispatchAddNotification({ result: "ERROR", message: error.msg });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 17:01:13