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

React中如何为同一元素同时实现短按和长按触发不同回调

长短按区分实现方案

原有代码问题排查

  • 所有事件回调都固定将startLongPress设为true、startShortPress设为false,完全没有短按逻辑的触发入口,所以短按永远不会执行
  • startLongPress状态一旦被设为true就没有重置为false的逻辑,useEffect会因为状态变化反复触发长按定时器,就会出现未按压也周期性触发长按的异常
  • 用state存储计时器触发标记会带来不必要的组件重渲染,性能较差

修正后的Hook实现

import { useRef, useCallback } from "react";

export default function useLongAndShortPress(
  longPressCallback: () => void = () => console.log("Long press callback"),
  shortPressCallback: () => void = () => console.log("Short press callback"),
  ms = 1000
) {
  // 存储长按定时器ID
  const timerRef = useRef<NodeJS.Timeout | null>(null);
  // 标记长按回调是否已经触发
  const longPressTriggeredRef = useRef(false);

  // 处理按压开始逻辑
  const handlePressStart = useCallback(() => {
    // 清空历史定时器避免重复触发
    if (timerRef.current) clearTimeout(timerRef.current);
    longPressTriggeredRef.current = false;
    // 开启长按计时
    timerRef.current = setTimeout(() => {
      longPressCallback();
      longPressTriggeredRef.current = true;
    }, ms);
  }, [longPressCallback, ms]);

  // 处理按压结束/取消逻辑
  const handlePressEnd = useCallback(() => {
    if (timerRef.current) {
      clearTimeout(timerRef.current);
      timerRef.current = null;
    }
    // 仅当长按未触发时执行短按回调
    if (!longPressTriggeredRef.current) {
      shortPressCallback();
    }
  }, [shortPressCallback]);

  return {
    onMouseDown: handlePressStart,
    onTouchStart: handlePressStart,
    onMouseUp: handlePressEnd,
    onMouseLeave: handlePressEnd,
    onTouchEnd: handlePressEnd,
    onTouchCancel: handlePressEnd,
  };
}

使用示例

使用方式和原有逻辑完全兼容,无需修改业务代码:

import useLongAndShortPress from './useLongAndShortPress';

function MyComponent (props) {
  const longAndShortPress = useLongAndShortPress(
    () => alert("LONG PRESS"), 
    () => alert("SHORT PRESS"), 
    1000
  );

  return (
    <Page>
      <Button {...longAndShortPress}>
        Click me
      </Button>
    </Page>
  );
};

方案优势

  • 内部状态用ref存储,不会触发组件额外重渲染,性能更优
  • 逻辑完全符合需求:按压时长不足阈值触发短按,达到阈值触发长按,长按触发后不再执行短按
  • 所有场景下都会自动清理定时器,不会出现内存泄漏或异常触发的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:27:03