use-double-click
use-double-click copied to clipboard
No double click detection with useEffect
I am trying to detect double clicks and single clicks on buttons.
function App() {
const buttonRef = useRef();
const [message, setMessage] = useState();
const [ws, setWS] = useState();
useEffect(() => {
const localWS = new WebSocket('ws://192.168.31.104:8000/ws');
localWS.onmessage = (event) => {}
}, []);
useDoubleClick({
onSingleClick: e => {
console.log(e, 'single click');
},
onDoubleClick: e => {
console.log(e, 'double click');
},
ref: buttonRef,
latency: 250
});
return <button ref={buttonRef}>Click Me</button>
}
export default App;
This function works perfectly, but when I try to change a state variable, the useDoubleClick hooks stops to detect double clicks.
function App() {
const buttonRef = useRef();
const [message, setMessage] = useState();
const [ws, setWS] = useState();
useEffect(() => {
const localWS = new WebSocket('ws://192.168.31.104:8000/ws');
localWS.onmessage = (event) => {
setMessage(JSON.parse(event.data)) // HERE
setWS(localWS); // HERE
}
}, []);
useDoubleClick({
onSingleClick: e => {
console.log(e, 'single click');
},
onDoubleClick: e => {
console.log(e, 'double click');
},
ref: buttonRef,
latency: 250
});
return <button ref={buttonRef}>Click Me</button>
}
What am I doing wrong?
can you create small demo app to check this problem?
Late but I was exploring this recently: The hook has no dependency array in it's useEffect so your setState
is resetting the internal click count, resulting in only single clicks being registered.
Does this sandbox work for you?
https://codesandbox.io/s/use-double-click-f7e33?expanddevtools=1&fontsize=14
Feel free to provide a repro of it not working
this pr will solve your issue once it's verified as production-ready: https://github.com/tim-soft/use-double-click/pull/32
additionally, you could THEORETICALLY add this component to your code and use it instead of directly calling useDoubleClick
but... better wait for the PR to pass
/**
* component that handles a rerender in the middle of the double click event.
* yes.
* seriously.
*/
const DoubleClickComponent = memo(function DoubleClickComponent<TClickableHTML extends HTMLElement>({
onSingleClick,
onDoubleClick,
clickableRef,
latency,
}: {
onSingleClick: (e: MouseEvent) => void;
onDoubleClick: (e: MouseEvent) => void;
clickableRef: MutableRefObject<TClickableHTML>;
latency?: number;
}) {
useDoubleClick({
onSingleClick,
onDoubleClick,
ref: clickableRef,
latency: latency,
});
return null;
});