Handling Keyboard Shortcuts in React

This morning I was working on adding a settings page to Clean Calendar. Right now there aren't many settings to toggle so I didn't feel a full page navigation was warranted so I decided to use a quick, slide-up dialog.

As a user, whenever I come across dialogs or modals or any other, uhh, "dismissable" UX patterns I instinctively hit the Escape key on my keyboard to try and dismiss them. If the dialog dismisses when I hit Escape then I think, "This app is solid and cares about UX". Maybe I'm the only one who thinks such things 😄. Regardless, I could not continue on with building out the settings dialog without being able to dismiss it via the keyboard.

Use a library or write it myself

So I did some quick research and there seems to be a few different libraries for dealing with keyboard shortcuts in React. I'm all for pulling in libraries when needed, but at this point I'm just trying to capture one little key press on one little screen... I'm not ready to pull in a library. Plus I want to learn how to do this "by hand" so that I can learn something new today.

How to handle the Escape key press

Javascript has a simple onKeyDown event, so I just used that. The first step was figuring out what element to listen to. I had 2 options, I could have listened on the Dialog component or on the Settings component. Since the whole point of listening to the escape key is to dismiss a dialog (and not a settings page) I listened to the onKeyDown event of the Dialog component.

So my first step was to add the onKeyDown event to the Dialog:

<Dialog open={this.state.showSettingsDialog} onKeyDown={this.handleKeyDown}>
  <Settings />
</Dialog>

And my next step was to add an arrow function defining handleKeyDown:

private handleKeyDown = event => {
  if (event.keyCode === 27) {
    this.setState({ ...this.state, showSettingsDialog: false });
  }
};

And now whenever the dialog is shown and I can hit the escape key and the dialog will be dismissed.

Escape dismissing dialog

Hopefully you found this post helpful, if you have any questions you can find me on Twitter.

Fixing Node Library Not Loaded icu4c Error
Fixing CSS Tap Effects on iOS