Rooks
HooksKeyboard & Input

useKeys

Calls a callback when every key in a configured combination is pressed.

About

useKeys tracks keydown and keyup state for a keyboard chord. The callback runs when every identifier in the list is currently marked as pressed.

Example

import { useState } from "react";
import { useKeys } from "rooks";

const saveShortcut = ["Control", "s"];

export default function ShortcutCounter() {
  const [saved, setSaved] = useState(0);

  useKeys(saveShortcut, (event) => {
    event.preventDefault();
    setSaved((count) => count + 1);
  });

  return <p>Press Control+S. Saves requested: {saved}</p>;
}

Parameters

  • keysList: an array of string identifiers compared with key, code, and legacy numeric event fields.
  • callback(event): receives the keydown event that completes the chord.
  • options.continuous: leaves the final identifier marked as pressed after a callback; defaults to false.
  • options.target: optional ref to Document or an element. A missing or currently null target falls back to document.
  • options.when: enables listeners; defaults to true.
  • options.preventLostKeyup: when true, clears tracked keys before alert, confirm, or prompt; defaults to false.

The options type is private and is shown inline.

Return value

The hook returns void.

Behavior and lifecycle

keydown marks matching identifiers and invokes the latest callback once all are truthy; keyup clears matches. With the default non-continuous mode, the identifier from the completing event is immediately marked false, although a repeated keydown can mark it true and trigger again. When preventLostKeyup is enabled, the hook temporarily replaces the three global dialog functions and restores them on cleanup. Event listeners and any dialog wrappers are removed when reconfigured or unmounted.

Compatibility and accessibility

The hook does nothing during server rendering. Global dialog replacement affects the whole page, so opt in only when needed. Keyboard layouts differ, and browser or assistive-technology shortcuts take priority. Provide a visible action and avoid firing shortcuts while users type into controls.

On this page