Is there a way to add long press event in react-web application?
I have list of addresses. On long press on any address, I want to fire event to delete that address followed by a confirm box.
To handle double click events in React:Add an onClick prop to the element. Use the detail property on the event object to get the click count. If the click count is equal to 2, handle the double click event.
Pressable is a Core Component wrapper that can detect various stages of press interactions on any of its defined children.
Creating a custom right-click menu in React. To create a right-click menu, we need to use the contextmenu event listener. This event fires when the user attempts to open a context menu. It is typically triggered by clicking the right mouse button, or by pressing the context menu keyboard shortcut.
I've created a codesandbox with a hook to handle long press and click. Basically, on mouse down, touch start events, a timer is created with setTimeout
. When the provided time elapses, it triggers long press. On mouse up, mouse leave, touchend, etc, the timer is cleared.
useLongPress.js
import { useCallback, useRef, useState } from "react"; const useLongPress = ( onLongPress, onClick, { shouldPreventDefault = true, delay = 300 } = {} ) => { const [longPressTriggered, setLongPressTriggered] = useState(false); const timeout = useRef(); const target = useRef(); const start = useCallback( event => { if (shouldPreventDefault && event.target) { event.target.addEventListener("touchend", preventDefault, { passive: false }); target.current = event.target; } timeout.current = setTimeout(() => { onLongPress(event); setLongPressTriggered(true); }, delay); }, [onLongPress, delay, shouldPreventDefault] ); const clear = useCallback( (event, shouldTriggerClick = true) => { timeout.current && clearTimeout(timeout.current); shouldTriggerClick && !longPressTriggered && onClick(); setLongPressTriggered(false); if (shouldPreventDefault && target.current) { target.current.removeEventListener("touchend", preventDefault); } }, [shouldPreventDefault, onClick, longPressTriggered] ); return { onMouseDown: e => start(e), onTouchStart: e => start(e), onMouseUp: e => clear(e), onMouseLeave: e => clear(e, false), onTouchEnd: e => clear(e) }; }; const isTouchEvent = event => { return "touches" in event; }; const preventDefault = event => { if (!isTouchEvent(event)) return; if (event.touches.length < 2 && event.preventDefault) { event.preventDefault(); } }; export default useLongPress;
To use the hook, App.js
import useLongPress from "./useLongPress"; export default function App() { const onLongPress = () => { console.log('longpress is triggered'); }; const onClick = () => { console.log('click is triggered') } const defaultOptions = { shouldPreventDefault: true, delay: 500, }; const longPressEvent = useLongPress(onLongPress, onClick, defaultOptions); return ( <div className="App"> <button {...longPressEvent}>use Loooong Press</button> </div> ); }
Older answer for class components:
You can use MouseDown, MouseUp, TouchStart, TouchEnd events to control timers that can act as a long press event. Check out the code below
class App extends Component { constructor() { super() this.handleButtonPress = this.handleButtonPress.bind(this) this.handleButtonRelease = this.handleButtonRelease.bind(this) } handleButtonPress () { this.buttonPressTimer = setTimeout(() => alert('long press activated'), 1500); } handleButtonRelease () { clearTimeout(this.buttonPressTimer); } render() { return ( <div onTouchStart={this.handleButtonPress} onTouchEnd={this.handleButtonRelease} onMouseDown={this.handleButtonPress} onMouseUp={this.handleButtonRelease} onMouseLeave={this.handleButtonRelease}> Button </div> ); } }
With hooks in react 16.8 you could rewrite class with functions and hooks.
import { useState, useEffect } from 'react'; export default function useLongPress(callback = () => {}, ms = 300) { const [startLongPress, setStartLongPress] = useState(false); useEffect(() => { let timerId; if (startLongPress) { timerId = setTimeout(callback, ms); } else { clearTimeout(timerId); } return () => { clearTimeout(timerId); }; }, [callback, ms, startLongPress]); return { onMouseDown: () => setStartLongPress(true), onMouseUp: () => setStartLongPress(false), onMouseLeave: () => setStartLongPress(false), onTouchStart: () => setStartLongPress(true), onTouchEnd: () => setStartLongPress(false), }; }
import useLongPress from './useLongPress'; function MyComponent (props) { const backspaceLongPress = useLongPress(props.longPressBackspaceCallback, 500); return ( <Page> <Button {...backspaceLongPress}> Click me </Button> </Page> ); };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With