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")
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.