Skip to content

Instantly share code, notes, and snippets.

@gragland
Created November 14, 2018 18:21
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save gragland/b61b8f46114edbcf2a9e4bd5eb9f47f5 to your computer and use it in GitHub Desktop.
Save gragland/b61b8f46114edbcf2a9e4bd5eb9f47f5 to your computer and use it in GitHub Desktop.
import { useState, useEffect } from 'react';
// Usage
function App() {
// Call our hook for each key that we'd like to monitor
const happyPress = useKeyPress('h');
const sadPress = useKeyPress('s');
const robotPress = useKeyPress('r');
const foxPress = useKeyPress('f');
return (
<div>
<div>h, s, r, f</div>
<div>
{happyPress && '😊'}
{sadPress && '😢'}
{robotPress && '🤖'}
{foxPress && '🦊'}
</div>
</div>
);
}
// Hook
function useKeyPress(targetKey) {
// State for keeping track of whether key is pressed
const [keyPressed, setKeyPressed] = useState(false);
// If pressed key is our target key then set to true
function downHandler({ key }) {
if (key === targetKey) {
setKeyPressed(true);
}
}
// If released key is our target key then set to false
const upHandler = ({ key }) => {
if (key === targetKey) {
setKeyPressed(false);
}
};
// Add event listeners
useEffect(() => {
window.addEventListener('keydown', downHandler);
window.addEventListener('keyup', upHandler);
// Remove event listeners on cleanup
return () => {
window.removeEventListener('keydown', downHandler);
window.removeEventListener('keyup', upHandler);
};
}, []); // Empty array ensures that effect is only run on mount and unmount
return keyPressed;
}
@alexrintt
Copy link

I would suggest adding 'blur' event to the window. I'm using this hook to see if 'Shift' is being pressed, but when I pressed 'Shift' and at same time go to another window (e.g devtools or another tab), the state wasn't being set as false, and when I went back to my tab the state was still true (since I release 'Shift' in another tab).

// ...

const setAsNotBeingPressed = useCallback(() => {
  setKeyPressed(false);
}, []);

const setAsBeingPressed = useCallback(() => {
  setKeyPressed(true);
}, []);

useEffet(() => {
  // ....
  window.addEventListener("blur", setAsBeingPressed);

  return () => {
    // ...
    window.removeEventListener("blur", setAsNotBeingPressed);
  }
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment