Skip to content

Instantly share code, notes, and snippets.

@Jayprecode
Forked from dimitrinicolas/README.md
Created October 3, 2022 20:32
Embed
What would you like to do?
Handle mouse down/up and click events once with React Hooks

Handle mouse down/up and click events once with React Hooks

The issue

Sometimes you need to make a button clickable with click and mouse down or mouse up actions.

The first solution that comes to mind would be to add only one event listener onMouseDown/onMouseUp but without an onClick event listener the element is not accessible anymore. It's now hard to click for people with disabilities or with keyboard navigation.

If we set both onMouseDown/onMouseUp and onClick event listeners, the common click handler function would be called twice with a mouse. So we have

We need to handle either one event or the other but not both, knowing that it can happen that only one of them is activated.

Improvement

This piece of code is subject to improvement, it needs to:

const onClick = () => { /** Handle mousedown or click */ }
const [mouseDown, setMouseDown] = useState(false);
useEffect(() => {
const handleDocumentMouseUp = event => {
if (event.button !== 2) {
setTimeout(() => setMouseDown(false), 10);
}
};
document.addEventListener('mouseup', handleDocumentMouseUp);
return () => {
document.removeEventListener('mouseup', handleDocumentMouseUp);
};
}, []);
const handleMouseDown = event => {
if (event.button !== 2) {
setMouseDown(true);
toggle();
}
};
const handleClick = useCallback(() => {
if (!mouseDown) {
onClick();
}
}, [mouseDown]);
return (
<button onMouseUp={handleMouseUp} onClick={handleClick}>
Click me
</button>
);
const onClick = () => { /** Handle mousedown or click */ }
const [clickTiggered, setClickTriggered] = useState(false);
const handleMouseUp = event => {
if (event.button !== 2) {
setClickTriggered(true);
setTimeout(() => setClickTriggered(false), 10);
onClick();
}
};
const handleClick = useCallback(() => {
if (!clickTiggered) {
onClick();
}
}, [clickTiggered]);
return (
<button onMouseUp={handleMouseUp} onClick={handleClick}>
Click me
</button>
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment