usehooks icon indicating copy to clipboard operation
usehooks copied to clipboard

useEventListener: Unable to bind event to specific dom element.

Open mitsuhatu opened this issue 3 years ago • 0 comments

As the title, when I use useEventListener to bind click event to dom element, it's not work.

function App() {
 const itemRef = useRef(null);

 const onMouseEnter = (e) => {
   console.log(e, 'enter');
 };

 const onMouseLeave = (e) => {
   console.log(e, 'leave');
 };

 useEventListener('mouseover', onMouseEnter, itemRef.current);
 useEventListener('mouseout', onMouseLeave, itemRef.current);

 return (
   <div className="App">
     <div ref={itemRef}>item</div>
   </div>
 );
}

Because ref.current from null to dom element, useEventListener will not update.

When I made the following adjustments, It will be OK.

  1. parameter: element replace by ref;
function App() {
  const itemRef = useRef(null);

  const onMouseEnter = (e) => {
    console.log(e, 'enter');
  };

  const onMouseLeave = (e) => {
    console.log(e, 'leave');
  };

  useEventListener('mouseover', onMouseEnter, itemRef);
  useEventListener('mouseout', onMouseLeave, itemRef);

  return (
    <div className="App">
      <div ref={itemRef}>item</div>
    </div>
  );
}
  1. use ref.current to bind event and adjust dependencies of useEffect;
function useEventListener(eventName, handler, ref) {
	const savedHandler = useRef();
	useEffect(() => {
		savedHandler.current = handler;
	}, [handler]);

	useEffect(() => {
		const element = ref ? ref.current : window;
		const isSupported = element && element.addEventListener;

		if (!isSupported) return;

		const eventListener = (event) => savedHandler.current(event);
                 element.addEventListener(eventName, eventListener);

		return () => {
			element.removeEventListener(eventName, eventListener);
		};
	}, [eventName, ref]);
}

mitsuhatu avatar Sep 08 '22 15:09 mitsuhatu