EN
React - useEvent() hook
7
points
In this short article, we would like to show how in React, create custom event listener hook that cleans up event automatically when component is removed.
Quick solution:
import {useRef, useEffect} from 'react';
const useEvent = (object, event, callback) => {
const ref = useRef(null);
useEffect(
() => {
const wrapper = (e) => {
if (ref.current) {
ref.current(e);
}
};
object.addEventListener(event, wrapper);
return () => object.removeEventListener(event, wrapper);
},
[object, event]
);
ref.current = callback;
};
// Usage example (put it into component):
useEvent(window, 'click', (e) => { /* ... */ });
Where:
objectargument indicates object for what we want to add event,eventargument indicates event name that we want to listen,
e.g.click,mousedown,mouseup,keydown,keyup, etc.,callbackargument indicates function that is called when event occurs on the object.
Practical example
In the below example we monitor 3 cases:
- when key is down,
- when key is up,
- and when window losts focus (
blurevent).
Source code:
// ONLINE-RUNNER:browser;
// import React from 'react';
// import ReactDOM from 'react-dom';
const useEvent = (object, event, callback) => {
const ref = React.useRef(null);
React.useEffect(
() => {
const wrapper = (e) => {
if (ref.current) {
ref.current(e);
}
};
object.addEventListener(event, wrapper);
return () => object.removeEventListener(event, wrapper);
},
[object, event]
);
ref.current = callback;
};
// Usage example:
const App = () => {
const [key, setKey] = React.useState(null);
useEvent(window, 'keydown', (e) => setKey(e.key));
useEvent(window, 'keyup', (e) => setKey(null));
useEvent(window, 'blur', (e) => setKey(null));
return (
<div>
<div>Click on this text to get focus and press some key on the keyboard!</div>
<div>
<span>Pessed key: </span>
<span>{key ?? '[UNDEFIEND]'}</span>
</div>
</div>
);
};
const root = document.querySelector('#root');
ReactDOM.render(<App />, root );