use-double-click icon indicating copy to clipboard operation
use-double-click copied to clipboard

No double click detection with useEffect

Open carlosporta opened this issue 3 years ago • 4 comments

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?

carlosporta avatar Nov 24 '21 16:11 carlosporta

can you create small demo app to check this problem?

vedro-compota avatar Jan 12 '22 09:01 vedro-compota

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.

episode17 avatar Apr 11 '24 22:04 episode17

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

tim-soft avatar Apr 12 '24 03:04 tim-soft

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;
});

TomerHir avatar Apr 22 '24 09:04 TomerHir