
Security News
Software Engineering Daily Podcast: Feross on AI, Open Source, and Supply Chain Risk
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.
react-keydown
Advanced tools
Use react-keydown as a higher-order component or decorator to pass keydown events to the wrapped component, or call methods directly via designated keys. Good for implementing keyboard navigation or other shortcuts.
Key advantages:
Consult the API & Reference Documentation or continue reading below for quick start.
NOTE: react-keydown doesn't use decorators itself, but to use the @keydown pattern in your application you will need a transpiler like Babel and a decorator transform plugin like this: https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy.
npm install --save react-keydown
The default build of react-keydown uses the CommonJS module system. For AMD or other support, use the umd-specific branch instead.
import React from 'react';
import keydown from 'react-keydown';
class MyComponent extends React.Component {
@keydown( 'enter' ) // or specify `which` code directly, in this case 13
submit( event ) {
// do something, or not, with the keydown event, maybe event.preventDefault()
MyApi.post( this.state );
}
}
Note: Since the only context we have for keydown events is the component, decorated methods receive the event as their sole argument and the component instance as context.
import keydown, { Keys } from 'react-keydown';
const { ENTER, TAB } = Keys; // optionally get key codes from Keys lib to check against later
@keydown( ENTER, TAB, 'ctrl+z' ) // could also be an array
autocomplete( event ) {
if ( event.which === ENTER ) { ... }
MyApi.get( this.state );
}
@keydown
class MyComponent extends React.Component {
componentWillReceiveProps( { keydown } ) {
if ( keydown.event ) {
// inspect the keydown event and decide what to do
console.log( keydown.event.which );
}
}
render() {
return (
<div>keydown events will only get passed down after this DOM node mounts or is clicked on</div>
);
}
}
export default MyComponent;
which you care about:const KEYS = [ 'shift+up', 'shift+down', 'enter', 'j', 'k', 'h', 'l' ];
@keydown( KEYS )
class MyComponent extends React.Component {
...
}
@keydownScoped shortcutWhen using the class decorator/higher-order component, decorate methods with @keydownScoped to identify the keydown.event prop as it comes in and bind certain values to methods:
import keydown, { keydownScoped } from 'react-keydown';
@keydown( 'enter' ) // optional to specify a key here. if called with just @keydown, all key events will get passed down
class MyComponent extends React.Component {
render() {
return <MyOtherComponent {...this.props} />;
}
}
class MyOtherComponent extends React.Component {
...
@keydownScoped( 'enter' ) // inspects nextProps.keydown.event in componentWillReceiveProps behind the scenes
submit() {
// submit
}
}
This is a convenience method, but also lets you specify a larger view context where this key binding should be active. Sometimes the component where the binding is declared is too small on its own.
This can also be a good way to set up app-wide shortcuts. Wrap your root component with @keydown and then use @keydownScoped or manually inspect the keydown.event props in the child components where those bindings are relevant.
In some cases you might want to handle all keys on your own. For that, you can specify the following:
import keydown, { ALL_KEYS } from 'react-keydown'
@keydown( ALL_KEYS )
handleKeys(ev) {
// handle keys here
}
Another useful feature is handling all printable characters.
import keydown, { ALL_PRINTABLE_KEYS } from 'react-keydown'
@keydown( ALL_PRINTABLE_KEYS )
beginEdit(ev) {
// Start editing
}
By default, bindings will not work when these fields have focus, in order not to interfere with user input and shortcuts related to these controls. You can override this in two ways:
Give your shortcut a ctrl modifier.
Since v1.6.0, there is experimental support for adding an onKeyDown binding to the element, specifying a method decorated with @keydown as the handler. For example:
class MyClass extends React.Component {
@keydown( 'a' )
myMethod( event ) {
console.log( event ); // should log only on 'a' keystroke, whether input is focused or not
}
render() {
return <input onKeyDown={ this.myMethod } />;
}
}
In the second case you could make multiple inputs work this way by spreading { onKeyDown: this.myMethod } into them, or by making this a reusable input component that takes the method as a prop (or composes multiple methods passed in as props).
Go to the live demo or:
$ open example/public/index.html
Note that this is very much a work in progress!
$ npm test
@keydown currently requires transpilation by
the Babel legacy decorators transform or the equivalent.@keydown( ... ) and then use
@keydownScoped( ... ) in the child components (or just inspect
nextProps.keydown.event in both).Why is this so limited, only working on keydown and such?
I published this out of my particular need on a project. If anyone else ever arrives here and needs something else let me know via issues or a pull request.
FAQs
Lightweight keydown wrapper for React components
We found that react-keydown demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.

Security News
GitHub has revoked npm classic tokens for publishing; maintainers must migrate, but OpenJS warns OIDC trusted publishing still has risky gaps for critical projects.

Security News
Rust’s crates.io team is advancing an RFC to add a Security tab that surfaces RustSec vulnerability and unsoundness advisories directly on crate pages.