简体   繁体   English

如何在 React 中的同一个元素上使用 onPress 和 onLongPress?

[英]How to have an onPress and onLongPress on the same element in React?

I have a button that I want to trigger different things depending on the duration of the press;我有一个按钮,我想根据按下的持续时间触发不同的事情; so one callback for short presses under 1000ms and another callback for long presses over 1000ms.所以1000毫秒以下的短按回调和1000毫秒以上的长按回调。 The short press callback should not be called if the long press callback is called.如果调用长按回调,则不应调用短按回调。

Building upon another user's solution for a long press only ( https://stackoverflow.com/a/54749871/11239421 ), I tried to create this React hook:基于另一个用户的长按解决方案( https://stackoverflow.com/a/54749871/11239421 ),我尝试创建这个 React 钩子:

import { useState, useEffect } from "react";

export default function useLongAndShortPress(
  longPressCallback = () => {
    console.log("Long press callback");
  },
  shortPressCallback = () => {
    console.log("Short press callback");
  },
  ms = 1000
) {
  const [startLongPress, setStartLongPress] = useState(false);
  const [startShortPress, setStartShortPress] = useState(false);

  useEffect(() => {
    let timerId: any;
    if (startLongPress) {
      timerId = setTimeout(longPressCallback, ms);
    } else if (startShortPress) {
      shortPressCallback();
      setStartShortPress(false);
    } else {
      clearTimeout(timerId);
    }

    return () => {
      clearTimeout(timerId);
    };
  }, [
    longPressCallback,
    shortPressCallback,
    ms,
    startLongPress,
    startShortPress,
  ]);

  return {
    onMouseDown: () => {
      setStartLongPress(true);
      setStartShortPress(false);
    },
    onMouseUp: () => {
      setStartLongPress(true);
      setStartShortPress(false);
    },
    onMouseLeave: () => {
      setStartLongPress(true);
      setStartShortPress(false);
    },
    onTouchStart: () => {
      setStartLongPress(true);
      setStartShortPress(false);
    },
    onTouchEnd: () => {
      setStartLongPress(true);
      setStartShortPress(false);
    },
    onTouchCancel: () => {
      setStartLongPress(true);
      setStartShortPress(false);
    },
  };
}

and then use this hook in a component:然后在组件中使用这个钩子:

import useLongAndShortPress from './useLongAndShortPress';

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

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

This doesn't work, as the short press callback is never triggered, and the long press callback seems to be triggered periodically even when not pressing the button at all.这不起作用,因为从未触发短按回调,即使根本不按下按钮,长按回调似乎也会定期触发。

Is there a better way to get both long and short presses on the same element, or are there any way to get my current solution to work?有没有更好的方法可以在同一个元素上同时进行长按和短按,或者有什么方法可以使我当前的解决方案发挥作用? Thank you very much :)非常感谢 :)

I managed to get it working.我设法让它工作。 I only changed the custom hook, so that it looked like this:我只更改了自定义钩子,使其看起来像这样:

import { useState, useEffect } from "react";

export default function useLongAndShortPress(
  longPressCallback = () => {
    console.log("Long press callback");
  },
  shortPressCallback = () => {
    console.log("Short press callback");
  },
  ms = 1000
) {
  const [startLongPress, setStartLongPress] = useState(false);
  const [startShortPress, setStartShortPress] = useState(false);

  useEffect(() => {
    let timerId: any;

    if (startLongPress) {
      timerId = setTimeout(() => {
        setStartShortPress(false);
        setStartLongPress(false);
        longPressCallback();
      }, ms);
    } else if (startShortPress) {
      setStartShortPress(false);
      shortPressCallback();

      clearTimeout(timerId);
    }

    return () => {
      clearTimeout(timerId);
    };
  }, [startLongPress, startShortPress]);

  return {
    onMouseLeave: () => {
      setStartLongPress(false);
    },
    onTouchStart: () => {
      setStartLongPress(true);
      setStartShortPress(true);
    },
    onTouchEnd: () => {
      setStartLongPress(false);
    },
  };
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM