React Hotkeys
React Hotkeys is a declarative library for managing keyboard shortcuts and focus within React applications. The current stable version is 2.0.0, representing a complete internal rewrite that removed the dependency on Mousetrap and now directly leverages React's SyntheticEvent system. This change significantly improved integration and predictable behavior within the React ecosystem. The library offers both component-based APIs (`<HotKeys>`, `<GlobalHotKeys>`, `<IgnoreKeys>`) and Higher-Order Components (`withHotKeys`, `withIgnoreKeys`) to define and handle hotkeys. Key features include support for standard browser key names and Mousetrap-like syntax, the ability to define global or context-specific hotkeys, dynamic hotkey configuration at runtime, and tools to display available shortcuts to users. It ships with comprehensive TypeScript types and is optimized for performance in large applications, with over 2000 automated tests ensuring reliability. Release cadence tends to be active during major version development, followed by maintenance releases.
Common errors
-
Legacy context API has been detected within a strict-mode tree
cause Using an older, deprecated way of accessing React context within a StrictMode component tree, leading to warnings.fixThis issue was specifically addressed in `react-hotkeys` v2.0.0-pre6. Ensure you are on the latest v2.x version to avoid this warning. The library is now compatible with React StrictMode. -
HotKeys not working for form fields/inputs
cause Hotkeys might be unintentionally blocked or not registering within standard HTML form elements (`input`, `textarea`, `select`), as `react-hotkeys` often ignores events from these elements by default.fixEnsure that the `HotKeys` component is correctly positioned in the component tree. Check the `allowEventPropagation` and `ignoreEventsCondition` configuration options, and review the 'What it actually means to ignore an event' documentation to customize this behavior. -
Global hotkeys throwing errors after dom changes
cause Dynamic DOM manipulation or unmounting/remounting components might interfere with how global hotkeys register and unregister their listeners, causing stale references or unexpected errors.fixThis was a known bug addressed in `react-hotkeys` v2.0.0-pre6. Ensure you are on the latest v2.x version to benefit from these fixes. If the issue persists, review how your components unmount and remount, and whether the `HotKeys` provider tree remains stable. -
Property 'ref' does not exist on type 'IntrinsicAttributes & HotKeysProps'
cause TypeScript error indicating an incorrect type definition for the `ref` prop when used directly with `HotKeys` components.fixThis was a known TypeScript type bug addressed in `react-hotkeys` v2.0.0-pre6. Ensure your TypeScript version and `react-hotkeys` version (>=2.0.0-pre6) are compatible. Use the `innerRef` prop instead of `ref` as specified by the library for accessing the underlying DOM node.
Warnings
- breaking Version 2.0.0 represents a complete internal rewrite, removing the Mousetrap dependency. Applications upgrading from v1.* will require significant changes to adapt to the new API and event handling system. The `__mousetrap__` property is no longer available.
- breaking The `<HotKeysIgnore />` component has been renamed to `<IgnoreKeys />`, and the `withHotKeysIgnore` HOC has been renamed to `withIgnoreKeys` for consistent naming conventions.
- breaking The keys `Delete` and `Backspace` (and the variant `del`) are no longer treated as aliases for one another. If you relied on this aliasing, you must now explicitly bind handlers to both keys.
- breaking `react-hotkeys` now ignores key combination submatches by default. This change addresses issues where shorter, context-dependent key combinations would hide longer, global ones, potentially preventing them from ever being triggered.
- breaking Repeated `keydown` events that occur when a key is held down are now ignored by default. This prevents a single long press from triggering an action multiple times.
- gotcha When the `Cmd` (Meta) key is pressed down, the `allowCombinationSubmatches` configuration option is ignored, and submatches are always allowed. This is a specific fix for navigating between `Cmd`+number hotkeys without releasing `Cmd`.
Install
-
npm install react-hotkeys -
yarn add react-hotkeys -
pnpm add react-hotkeys
Imports
- HotKeys
import HotKeys from 'react-hotkeys';
import { HotKeys } from 'react-hotkeys'; - GlobalHotKeys
import { HotKeys } from 'react-hotkeys/global';import { GlobalHotKeys } from 'react-hotkeys'; - IgnoreKeys
import { HotKeysIgnore } from 'react-hotkeys';import { IgnoreKeys } from 'react-hotkeys'; - withHotKeys
const withHotKeys = require('react-hotkeys').withHotKeys;import { withHotKeys } from 'react-hotkeys'; - configure
import { HotKeys } from 'react-hotkeys'; HotKeys.configure({...});import { configure } from 'react-hotkeys';
Quickstart
import { HotKeys } from "react-hotkeys";
import React, { useCallback } from 'react';
const keyMap = {
SNAP_LEFT: "command+left",
DELETE_NODE: ["del", "backspace"]
};
const MyNode = () => {
const deleteNode = useCallback(() => {
console.log('Delete node action triggered!');
// Implement your node deletion logic here
}, []);
const handlers = {
DELETE_NODE: deleteNode
};
return (
<HotKeys handlers={handlers}>
<div style={{ padding: '20px', border: '1px solid #ccc', margin: '10px' }}>
Node contents. Press 'Del' or 'Backspace' to delete.
</div>
</HotKeys>
);
};
const App = () => {
return (
<HotKeys keyMap={keyMap}>
<div style={{ fontFamily: 'sans-serif' }}>
<h1>React Hotkeys Demo</h1>
<p>Focus this area and try hotkeys. Command+Left is global, Del/Backspace is on MyNode.</p>
<MyNode />
<MyNode />
<input type="text" placeholder="Type here to test input ignore" style={{ marginTop: '20px' }} />
</div>
</HotKeys>
);
};
export default App;