Skip to content

Instantly share code, notes, and snippets.

@mrzmyr
Created November 22, 2015 16:56
Show Gist options
  • Star 49 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save mrzmyr/9ac94ca4622c1602a2a3 to your computer and use it in GitHub Desktop.
Save mrzmyr/9ac94ca4622c1602a2a3 to your computer and use it in GitHub Desktop.
React Native - Detect Double Tap
var Index = React.createClass({
getInitialState: function () {
return {
lastPress: 0
}
},
onPress: function () {
var delta = new Date().getTime() - this.state.lastPress;
if(delta < 200) {
// double tap happend
}
this.setState({
lastPress: new Date().getTime()
})
},
render: function() {
return (
<TouchableHighlight onPress={this.onPress}></TouchableHighlight>
)
}
});
@yanickrochon
Copy link

yanickrochon commented Aug 12, 2022

@fukemy I'm not certain what you mean, of course I have read @iksent 's comment. Back in 2020, React hooks were relatively new. So, if I would rewrite the code I posted, it would more look like this one, today :

const MultiPressOverlay: () => ReactNode = ({
  delayLongPress = 1000,
  delayMultiPress = 300,
  minMultiPress = 4,
  onPress,
  onLongPress,
  onMultiPress,
  children
}) => {
  const [lastPress, setLastPress] = useState(null);
  const [pressCount, setPressCount] = useState(0);

  useEffect(() => {
    if ((pressCount > 1) && (pressCount >= minMultiPress)) {
      setPressCount(0);
      onMultiPress && onMultiPress(new CustomEvent("multipress", { detail: { pressCount } }));
    }
  }, [pressCount, minMultiPress, onMultiPress]);

  const handlePress = evt => {
    const now = Date.now();

    setLastPress(now);
    if (now - lastPress <= delayMultiPress) {
       setPressCount(pressCount => pressCount + 1);
    } else {
      setPressCount(1);
    }

    onPress && onPress(evt);
  };

  return (
    <TouchableOpacity
      delayLongPress={ delayLongPress }
      activeOpacity={ 0.8 }
      onLongPress={ onLongPress }
      onPress={ handlePress }
    >
      { children }
    </TouchableOpacity>
  );
};

NOTE: There is still a lot of room for improvement, but this was written without tests whatsoever. I would move the onPress inside the useEffect callback, with a timer, to trigger a single press event is the delayMultiPress is expired and less than minMultiPress has beeen triggered, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment