Reputation: 2639
I have a ReactJS component below. I want to listen for a key down even if my component is not in focus. It will always be rendered but it is not the only component on the web page. The event listener will call a function when I push the SHIFT key down. The component is not the topmost component on my web page; it has a parent.
Component extends React.Component {
componentWillMount(): void {
document.addListener('keyDown', this._handleKeyDown);
}
componentWillUnmount(): void {
document.removeListender('keyDown', this._handleKeyDown);
}
}
Sometimes it will behave properly when I push a button but sometimes I actually have to click on this component again to get it to acknowledge the key press.
How can I ensure it always listens for the key press? Is it advisable to add an event listener to document in a lower level component?
Upvotes: 0
Views: 79
Reputation: 2639
It wasn't working because I had a very large invisible div in front of my clickable element. I made the div have no pointer events and then I was able to get my keyDown function consistently working.
The technique above will work. You can put document.addEventListener inside a child React component.
Upvotes: 0
Reputation: 471
pen here -> http://codepen.io/dagman/pen/mAOrVP
const App = ({
handleOnKeyDown,
keyCode
}) => (
<div>
<input
style={styles.input}
onKeyDown={handleOnKeyDown}
placeholder="Press any key to see it's code on right"
/>
<span style={styles.span}>{keyCode}</span>
</div>
);
class AppContainer extends React.Component {
constructor(props) {
super();
this.state = {
keyCode: null
};
}
handleOnKeyDown(e) {
this.setState({
keyCode: e.keyCode
});
}
render() {
return(
<App
handleOnKeyDown={this.handleOnKeyDown.bind(this)}
keyCode={this.state.keyCode}
/>
);
}
}
const mountNode = document.getElementById('app');
const styles = {
input: {
width: 300,
height: 50
},
span: {
color: 'white',
marginLeft: 5
}
};
ReactDOM.render(
<AppContainer />,
mountNode
);
Is it what you were asking about?
Upvotes: 1