Reputation: 2204
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>
);
}
}
Upvotes: 6
Views: 14543
Reputation: 4540
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
Upvotes: 3
Reputation:
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!
Upvotes: 8