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:
object
argument indicates object for what we want to add event,event
argument indicates event name that we want to listen,
e.g.click
,mousedown
,mouseup
,keydown
,keyup
, etc.,callback
argument 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 (
blur
event).
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 );