Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A React hook for handling keypresses
import { useState, useEffect, useRef } from "react";
interface Parameters {
key: string;
ctrlKey?: boolean;
shiftKey?: boolean;
metaKey?: boolean;
onKeyDown?: (e: KeyboardEvent) => void;
onKeyUp?: (e: KeyboardEvent) => void;
}
const checkKeyValidity = (e: KeyboardEvent, params: Parameters) => {
return (
e.key === params.key &&
e.ctrlKey === !!params.ctrlKey &&
e.metaKey === !!params.metaKey &&
e.shiftKey === !!params.shiftKey
);
};
export function useKeyboardPress(params: Parameters) {
const [isKeyDown, setIsKeyDown] = useState(false);
const shouldDisableKeyDownUpdate = useRef(false);
const handleKeyDown = (e: KeyboardEvent) => {
const isKeyValid = checkKeyValidity(e, params);
if (isKeyValid) {
if (params.onKeyDown) {
params.onKeyDown(e);
}
if (!shouldDisableKeyDownUpdate.current) {
shouldDisableKeyDownUpdate.current = true;
setIsKeyDown(true);
}
}
};
const handleKeyUp = (e: KeyboardEvent) => {
shouldDisableKeyDownUpdate.current = false;
if (params.onKeyUp) {
params.onKeyUp(e);
}
setIsKeyDown(false);
};
useEffect(() => {
window.document.addEventListener("keydown", handleKeyDown);
window.document.addEventListener("keyup", handleKeyUp);
return () => {
window.document.removeEventListener("keydown", handleKeyDown);
window.document.removeEventListener("keyup", handleKeyUp);
};
}, []);
return isKeyDown;
}
@mmazzarolo

This comment has been minimized.

Copy link
Owner Author

mmazzarolo commented Dec 30, 2018

Usage examples

Check if the tab key is down

const isTabDown = useKeyboardPress({
  key: "Tab"
})

Invoke a callback when the A key is pressed

useKeyboardPress({
  key: "a",
  onKeyDown: () => {
    console.log(`Key "a" has been pressed`);
  }
})

Combination of the two examples above

const isBDown = useKeyboardPress({
  key: "b",
  onKeyDown: () => {
    console.log(`Key "b" has been pressed`);
  }
})

Override CTRL + F search (on Windows)

useKeyboardPress({
  key: "f",
  ctrlKey: true,
  onKeyDown: (e) => {
    e.preventDefault();
    console.log(`CTRL + F has been pressed`);
    handleSearchPress();
  }
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.