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

React如何限制函数短时间内被频繁调用

实现函数的2秒节流限制(立即执行版)

你需要的是**节流(Throttle)**机制——允许函数立即执行一次,之后在指定时间内(这里是2秒)无法再次触发,正好匹配你防止短时间内多次调用setNextPage/setPrevPage的需求。

方式一:直接在事件处理中添加时间判断(简单直观)

在组件中通过useRef存储两个分页函数的上次调用时间戳(useRef的值不会随组件渲染重置,适合跨渲染周期保存状态),每次触发时检查时间间隔是否满足要求:

import { useRef, useState } from 'react';

// 组件内部
const calendarContainerRef = useRef<HTMLDivElement>(null);
const [dragMode, setDragMode] = useState(true); // 假设dragMode是组件状态

// 记录上次调用时间的ref
const lastNextCall = useRef<number>(0);
const lastPrevCall = useRef<number>(0);
const THROTTLE_DELAY = 2000; // 2秒限制

const handleMouseMove = (event: React.MouseEvent) => {
  if (dragMode) {
    setDragMode(false);
    const bounds = event.currentTarget.getBoundingClientRect();
    const xPosition = event.clientX - bounds.left;
    const now = Date.now();

    // 处理setNextPage的节流
    if (xPosition > (calendarContainerRef.current?.clientWidth || 0) - 20) {
      if (now - lastNextCall.current >= THROTTLE_DELAY) {
        setNextPage();
        lastNextCall.current = now; // 更新上次调用时间
      }
    }

    // 处理setPrevPage的节流
    if (xPosition < 90) {
      if (now - lastPrevCall.current >= THROTTLE_DELAY) {
        setPrevPage();
        lastPrevCall.current = now; // 更新上次调用时间
      }
    }
  }
};

return (
  <Scheduler onMouseMove={handleMouseMove} />
);

方式二:封装通用节流Hook(复用性强)

如果需要在多个地方使用节流逻辑,可以封装一个通用的useThrottle Hook,简化代码:

import { useRef, useCallback } from 'react';

// 通用节流Hook
const useThrottle = (fn: () => void, delay: number) => {
  const lastCall = useRef(0);

  return useCallback(() => {
    const now = Date.now();
    if (now - lastCall.current >= delay) {
      fn();
      lastCall.current = now;
    }
  }, [fn, delay]);
};

// 组件内部使用
const throttledNextPage = useThrottle(setNextPage, 2000);
const throttledPrevPage = useThrottle(setPrevPage, 2000);

const handleMouseMove = (event: React.MouseEvent) => {
  if (dragMode) {
    setDragMode(false);
    const bounds = event.currentTarget.getBoundingClientRect();
    const xPosition = event.clientX - bounds.left;

    if (xPosition > (calendarContainerRef.current?.clientWidth || 0) - 20) {
      throttledNextPage(); // 直接调用节流后的函数
    }
    if (xPosition < 90) {
      throttledPrevPage(); // 直接调用节流后的函数
    }
  }
};

关键说明:

  • 两种方式都保证了函数立即执行第一次调用,之后必须等待2秒才能再次触发。
  • useRef用于存储时间戳,避免组件渲染时重置状态。
  • 方式二的useCallback确保节流函数不会随组件渲染频繁重建,优化性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 12:05:43