Skip to content

Instantly share code, notes, and snippets.

@keidarcy
Created September 2, 2020 02:58
Show Gist options
  • Save keidarcy/e083cf8dd805cb68d0b73aa2d574af3b to your computer and use it in GitHub Desktop.
Save keidarcy/e083cf8dd805cb68d0b73aa2d574af3b to your computer and use it in GitHub Desktop.
custom addEventListener hook with typescript
import React, { useEffect, useRef, useState } from 'react';
import logo from './logo.svg';
import './App.css';
interface Options {
enable?: boolean;
target?: GlobalEventHandlers;
}
const useEventListener = (
targetEvent: keyof GlobalEventHandlersEventMap,
handler: (e: Event) => void,
{ enable = true, target = document }: Options = {}
) => {
const handlerRef = useRef(handler);
const internalHandler = (e: Event) => {
handlerRef.current(e);
};
useEffect(() => {
handlerRef.current = handler;
});
useEffect(() => {
if (!enable) {
console.log('enable in');
return;
}
target.addEventListener(targetEvent, internalHandler);
return () => {
target.removeEventListener(targetEvent, internalHandler);
};
}, [targetEvent, enable, target]);
};
function App() {
const [enable, setEnable] = useState(false);
const [count, setCount] = useState(0);
useEventListener(
'click',
() => {
console.log('object', count);
},
{ enable }
);
useEventListener(
'scroll',
() => {
console.log('SCROLLLLL');
},
{ target: window }
);
return (
<div className="App" style={{ height: '2000px' }}>
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a className="App-link" href="#" target="_blank" rel="noopener noreferrer">
{count}
</a>
<button onClick={() => setEnable(!enable)}>Enable: {enable.toString()}</button>
<button onClick={() => setCount(count + 1)}>click</button>
</header>
</div>
);
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment