6

My goal is to call the setEditing () function in the Todo component. I have created a keyboard shortcut:

const keyMap = { TEST: "t" }; const handlers = { TEST: () => this.setEditing() }; const MyHotKeysComponent = withHotKeys (Todo, {keyMap, handlers}); <MyHotKeysComponent> <p> press t </p> </ MyHotKeysComponent> 

In which part of the Todo component do you place these elements?


Code here: https://stackblitz.com/edit/react-cjkf1d?file=index.js

import { withHotKeys } from "react-hotkeys"; class EditForm extends React.Component { render() { return ( <div> <textarea onChange={(e) => this.props.handleDescription(e)} value={this.props.description}></textarea> <button onClick={this.props.onSave} type="submit">Save</button> <button onClick={this.props.onCancel} type="submit">Cancel</button> </div> ) } } class Todo extends Component { constructor(props) { super(props); this.state = { isEditing: false } } setEditing = () => { this.setState({ isEditing: !this.state.isEditing }) } render() { const { hotKeys, ...remainingProps } = this.props; return ( <div {...{ ...hotKeys, ...remainingProps }}> {this.state.isEditing ? (<EditForm handleChange={this.handleChange} />) : ( <li> <div> {this.props.todo.date} </div> <div> {this.props.todo.description} </div> <button onClick={() => this.setEditing()}>Edit</button> </li> ) } </div> ) } } const keyMap = { TEST: "t" }; const handlers = { TEST: () => this.setEditing() }; const MyHotKeysComponent = withHotKeys(Todo, { keyMap, handlers }); <MyHotKeysComponent> <p>press t</p> </MyHotKeysComponent> class App extends React.Component { constructor() { super(); this.state = { todos: [ { date: '2019-12-09', description: 'Hello' } ], }; } render() { return ( <div> <ul> { this.state.todos .map((todo, index) => <Todo key={index} index={index} todo={todo} /> ) } </ul> </div> ); } } 

2 Answers 2

8
+25

You can use HotKeys instead of withHotKeys to handle the event of the component.

I have created small demo for you to handle the event key press.

import { HotKeys } from "react-hotkeys"; import React, { Component } from 'react'; import { render } from 'react-dom'; class MyComponent extends Component { constructor(props) { super(props); this.state = { isEditing: true } this.keyMap = { TEST: "t" }; this.handlers = { TEST: (e) => { this.setEditing(); } }; } setEditing = () => { this.setState({ isEditing: !this.state.isEditing }) } render() { return ( <HotKeys keyMap={this.keyMap} handlers={this.handlers} > <span>My HotKeys are effective here</span><br /> <b>isEditing: {this.state.isEditing.toString()}</b><br /> {this.props.children} </HotKeys> ); } } render(<MyComponent />, document.getElementById('root')); 


Keyboard shortcuts in React, the react-hotkeys library

Updated Code: https://stackblitz.com/edit/react-hotkeys-demo?embed=1&file=index.js

I have updated your code and it's working as expected.

import React, { Component } from 'react'; import { render } from 'react-dom'; import Hello from './Hello'; import './style.css'; import { HotKeys } from "react-hotkeys"; class EditForm extends React.Component { render() { return ( <div> <textarea onChange={(e) => this.props.handleDescription(e)} value={this.props.description}></textarea> <button onClick={this.props.onSave} type="submit">Save</button> <button onClick={this.props.onCancel} type="submit">Cancel</button> </div> ) } } class Todo extends Component { constructor(props) { super(props); this.state = { isEditing: false } this.keyMap = { TEST: "t" }; this.handlers = { TEST: () => this.setEditing() }; } setEditing = () => { this.setState({ isEditing: !this.state.isEditing }) } render() { return ( <HotKeys keyMap={this.keyMap} handlers={this.handlers} > {this.state.isEditing ? <EditForm handleChange={this.handleChange} /> : <li> <div> {this.props.todo.date} </div> <div> {this.props.todo.description} </div> <button onClick={() => this.setEditing()}>Edit</button> </li> } </HotKeys> ) } } class App extends React.Component { constructor() { super(); this.state = { todos: [ { date: '2019-12-09', description: 'Hello' } ], }; } render() { return ( <div> <ul> {this.state.todos.map((todo, index) => <Todo key={index} index={index} todo={todo} /> )} </ul> </div> ); } } render(<App />, document.getElementById('root')); 

Hope this will help to you!

Sign up to request clarification or add additional context in comments.

10 Comments

I pressed t but nothing happens in your demo
I have noticed now that I have to click on the component first, then press t. And you can't do it to work without selecting a component? I open the demo, press t--> function this.setEditing() calls.
That's the behavior of the react-hotkeys npm library. So you have to select the component. In alternative way might be you can auto select the component onload.
How can auto select the component onload? Can you explain me?
By using ref you can do it. Set ref="divFocus" to div and set focus by this command ReactDOM.findDOMNode(this.refs.divFocus).focus();
|
3

My goal is to call the setEditing () function in the Todo component.

You can call setEditing function on keyPress without using react-hotkeys.

I used React's onKeyDown keyboard event to catch user's key presses.

onKeyDown={(e) => this.handleKeyPress(e)} 

In handleKeyPress() function, I check the keyCode to determine which key was pressed by user. KeyCode of t is 84. If keyCode is equal to 84, invoke setEditing function. Like this:

 handleKeyPress = e => { e.keyCode === 84 && this.setEditing(); } 

Also, you can use a ref to focus to the div, which is the target element for the key press event. So, you don't have to click on it before pressing t.

Demo is here: https://react-pgr9pt.stackblitz.io

Code is here: https://stackblitz.com/edit/react-pgr9pt

4 Comments

e.key === 't'?
@user9408899 When I open the demo, I click indifferently where this focus disappears. Can it be done so that it does not disappear? Someone accidentally clicks and the shortcut won't work.
@Umbro this will not work for you because it will also making trouble to write the text in input. Try to write "test" word in input area and see this will not work. So you can not bind the event with document keydown.
!this.state.isEditing condition can be added after e.keyCode === 84 to overcome that. @ClueMediator

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.