Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React not responding to key down event

I'm trying to implement some very basic key press detection and I can't get it to work at all. I have a bare component that should be picking up on the onKeyDown event but nothing gets logged out in the console:

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  handleKeyDown(event) {
    console.log('handling a key press');
  }

  render() {
    return (
      <ChildComponent onKeyDown={this.handleKeyDown} />
    );
  }
}

React.render(<App />, document.getElementById('app'));
like image 338
Simpleton Avatar asked Aug 27 '15 16:08

Simpleton


People also ask

How do you handle keyboard events in React JS?

The onKeyPress event in ReactJS occurs when the user presses a key on the keyboard but it is not fired for all keys e.g. ALT, CTRL, SHIFT, ESC in all browsers. To use the onKeyPress event in ReactJS we will use the predefined onKeyPress method.

What is the difference between Onkeydown and onKeyPress?

onkeydown is fired when the key is down (like in shortcuts; for example, in Ctrl+A , Ctrl is held 'down'. onkeypress is fired as a combination of onkeydown and onkeyup , or depending on keyboard repeat (when onkeyup isn't fired).

How do I use onKeyUp in React?

Use the React. KeyboardEvent<HTMLElement> type to type the onKeyUp event in React. The KeyboardEvent interface is used for onKeyUp events. You can access the value of the key pressed by the user as event.


2 Answers

You'll need to assign a tabIndex-attribute for your element (the wrapping element for example) for it to receive keypresses. Then pass the keyDown handler to it with the props:

import React from 'react';
import { render } from 'react-dom';

class ChildComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div tabIndex="0" onKeyDown={this.props.handleKeyDown}>Fooo</div> 
    );
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  handleKeyDown(event) {
    console.log('handling a key press');
  }

  render() {
    return (
      <ChildComponent handleKeyDown={() => this.handleKeyDown()} />
    );
  }
}

render(<App />, document.getElementById('app')); 
like image 156
Pete TNT Avatar answered Sep 17 '22 19:09

Pete TNT


The DOM wants the element to be focused in order to receive the keyboard event. If you don't want to hack the element with tabIndex or contentEditable to get it to focus, you could use native DOM event listeners on window, and define a different handler in each component that handles keyboard events.

Just be sure to remove the event listener when that component unmounts so all components aren't handling all the time:

  componentWillMount: function() {
    window.addEventListener('keydown', this.handleKeyDown);
  },

  componentWillUnmount: function() {
    window.removeEventListener('keydown', this.handleKeyDown);
  },

Also, there appears to be an npm that provides similar functionality if that's easier: https://www.npmjs.com/package/react-keydown

like image 42
Benny Nightingale Avatar answered Sep 21 '22 19:09

Benny Nightingale