我正在尝试使用React在Atom编辑器包中渲染视图。我遇到的一个问题是输入字段中的onKeyDown事件处理程序永远不会触发。相反,使用onKeyPress确实可以,但是我需要onKeyDown事件才能工作。
我可以让ReactDOM onKeyDown事件在不属于Atom包的React应用程序中工作,并且可以让DOM keydown事件在不使用React时在Atom包中工作。出于某种原因,当同时使用React和Atom时,onKeyDown事件不会触发。
如何使React onKeyDown事件在Atom程序包中触发?
'use babel';
import React from 'react';
import ReactDOM from 'react-dom';
class Panel extends React.Component {
constructor(props) {
super(props);
this.ref = React.createRef();
}
componentDidMount() {
console.log('componentDidMount');
this.ref.current.value = 'Enter text';
}
render() {
/* In the following code neither onKeyDown nor onKeyUp generate a console log;
however, using onKeyPress works correctly */
return (
<div>
<div className="message">
{ 'The KeydownIssueView package is Alive! It\'s ALIVE!' }
</div>
<input ref={this.ref}
type="text"
id="inputId"
tabIndex="1"
className="native-key-bindings"
onKeyDown={ (e) => console.log('onKeyDown', e.nativeEvent) }
/>
</div>
);
}
}
export default class KeydownIssueView {
constructor(serializedState) {
this.element = document.createElement('div');
this.element.classList.add('keydown-issue');
/* The following code, when un-commented and used without React, works.
const message = document.createElement('div');
message.textContent = 'The KeydownIssue package is Alive! It\'s ALIVE!';
message.classList.add('message');
this.element.appendChild(message);
const input = document.createElement('input');
input.addEventListener('keydown', (e) => console.log('keydown', e))
this.element.appendChild(input);
*/
ReactDOM.render(<Panel />, this.element);
}
serialize() {}
destroy() { this.element.remove(); }
getElement() { return this.element; }
}
'use babel';
import KeydownIssueView from './keydown-issue-view';
import { CompositeDisposable } from 'atom';
export default {
keydownIssueView: null,
panel: null,
subscriptions: null,
activate(state) {
this.keydownIssueView = new KeydownIssueView(state.keydownIssueViewState);
this.panel = atom.workspace.addBottomPanel({
item: this.keydownIssueView.getElement(),
visible: false
});
this.subscriptions = new CompositeDisposable();
this.subscriptions.add(atom.commands.add('atom-workspace', {
'keydown-issue:toggle': () => this.toggle()
}));
},
deactivate() {
this.panel.destroy();
this.subscriptions.dispose();
this.keydownIssueView.destroy();
},
serialize() {
return {
keydownIssueViewState: this.keydownIssueView.serialize()
};
},
toggle() {
return (
this.panel.isVisible() ?
this.panel.hide() :
this.panel.show()
);
}
};