Skip to content

Instantly share code, notes, and snippets.

@dimitrinicolas
Last active December 18, 2023 11:42
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dimitrinicolas/f8768ae7b664b6259eb923157b16d4fc to your computer and use it in GitHub Desktop.
Save dimitrinicolas/f8768ae7b664b6259eb923157b16d4fc to your computer and use it in GitHub Desktop.
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>
);
@KIranMehta075
Copy link

can you give code for mouse down. that will be best!!!

@dimitrinicolas
Copy link
Author

can you give code for mouse down. that will be best!!!

Have you seen this repository: https://github.com/dimitrinicolas/use-mouse-action ?

It is the evolution of this gist exploration.

@KIranMehta075
Copy link

Thanks!!! but I was talking about handle mouse down or click logic code.

@dimitrinicolas
Copy link
Author

dimitrinicolas commented Mar 6, 2021 via email

@KIranMehta075
Copy link

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 (

Click me

);
I was talking about this code. can you give Handle mousedown code?

@dimitrinicolas
Copy link
Author

You'll have to put your own logic into onClick function.

I really encourage you tu use this library instead of this gist code: https://github.com/dimitrinicolas/use-mouse-action

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