Dec 28, 2021

useMousetrap()

I've been messing around with a React implementation of The Lounge lately (for no real reason except that I can) and wanted a functional way to use Mousetrap, which TL already uses. The below hook let me replace the Vue use of Mousetrap (which was pretty much vanilla JS) in a React-like fashion. For bonus typing, add @types/mousetrap to your project.

Usage is pretty simple:

useMousetrap("escape", (evt, combo) => {
evt.preventDefault
}, "keypress")
useMousetrap("escape", (evt, combo) => {
evt.preventDefault
}, "keypress")
import mousetrap from "mousetrap"
import { useEffect, useRef } from "react"

const useMousetrap = (
handlerKey: string | string[],
handlerCallback: (evt: KeyboardEvent, combo: string) => void,
evtType?: "keypress" | "keydown" | "keyup",
) => {
let actionRef = useRef(handlerCallback)

useEffect(() => {
mousetrap.bind(
handlerKey,
(evt: KeyboardEvent, combo: string) => {
typeof actionRef.current === "function" && actionRef.current(evt, combo)
},
evtType,
)
return () => {
mousetrap.unbind(handlerKey)
}
}, [evtType, handlerKey])
}

export default useMousetrap
import mousetrap from "mousetrap"
import { useEffect, useRef } from "react"

const useMousetrap = (
handlerKey: string | string[],
handlerCallback: (evt: KeyboardEvent, combo: string) => void,
evtType?: "keypress" | "keydown" | "keyup",
) => {
let actionRef = useRef(handlerCallback)

useEffect(() => {
mousetrap.bind(
handlerKey,
(evt: KeyboardEvent, combo: string) => {
typeof actionRef.current === "function" && actionRef.current(evt, combo)
},
evtType,
)
return () => {
mousetrap.unbind(handlerKey)
}
}, [evtType, handlerKey])
}

export default useMousetrap

Thanks for reading! If you want to see future content, you can follow me on Twitter or subscribe to my RSS feed.