snippetjavascriptreactCritical
How to detect Esc Key Press in React and how to handle it
Viewed 0 times
keyandpressescreactdetecthowhandle
Problem
How do I detect Esc keypress on reactjs? The similar thing to jquery
Once detected I want to pass the info down components. I have 3 components out of which last active component needs to react to the escape key press.
I was thinking of a kind of registering when a component becomes active
and on all the components
I believe this will work but I think it will be more like a callback. Is there any better way to handle this?
$(document).keyup(function(e) {
if (e.keyCode == 27) { // escape key maps to keycode `27`
//
}
});Once detected I want to pass the info down components. I have 3 components out of which last active component needs to react to the escape key press.
I was thinking of a kind of registering when a component becomes active
class Layout extends React.Component {
onActive(escFunction){
this.escFunction = escFunction;
}
onEscPress(){
if(_.isFunction(this.escFunction)){
this.escFunction()
}
}
render(){
return (
)
}
}and on all the components
class ActionPanel extends React.Component {
escFunction(){
//Do whatever when esc is pressed
}
onActive(){
this.props.onActive(this.escFunction.bind(this));
}
render(){
return (
)
}
}I believe this will work but I think it will be more like a callback. Is there any better way to handle this?
Solution
If you're looking for a document-level key event handling, then binding it during
Note that you should make sure to remove the key event listener on unmount to prevent potential errors and memory leaks.
EDIT: If you are using hooks, you can use this
EDIT for React 17: React changed the way that document-level event binding is handled, which may cause this implementation to stop working if at some point in the chain
componentDidMount is the best way (as shown by Brad Colthurst's codepen example):class ActionPanel extends React.Component {
constructor(props){
super(props);
this.escFunction = this.escFunction.bind(this);
}
escFunction(event){
if (event.key === "Escape") {
//Do whatever when esc is pressed
}
}
componentDidMount(){
document.addEventListener("keydown", this.escFunction, false);
}
componentWillUnmount(){
document.removeEventListener("keydown", this.escFunction, false);
}
render(){
return (
)
}
}Note that you should make sure to remove the key event listener on unmount to prevent potential errors and memory leaks.
EDIT: If you are using hooks, you can use this
useEffect structure to produce a similar effect:const ActionPanel = (props) => {
const escFunction = useCallback((event) => {
if (event.key === "Escape") {
//Do whatever when esc is pressed
}
}, []);
useEffect(() => {
document.addEventListener("keydown", escFunction, false);
return () => {
document.removeEventListener("keydown", escFunction, false);
};
}, [escFunction]);
return (
)
};EDIT for React 17: React changed the way that document-level event binding is handled, which may cause this implementation to stop working if at some point in the chain
event.stopPropogation() is called. You can ensure that this function is called first by changing the last argument of the listener to true rather than false. If you do this and also call event.stopPropogation(), other handlers that used to be called will no longer take place, so I would suggest avoiding that call if at all possible.Code Snippets
class ActionPanel extends React.Component {
constructor(props){
super(props);
this.escFunction = this.escFunction.bind(this);
}
escFunction(event){
if (event.key === "Escape") {
//Do whatever when esc is pressed
}
}
componentDidMount(){
document.addEventListener("keydown", this.escFunction, false);
}
componentWillUnmount(){
document.removeEventListener("keydown", this.escFunction, false);
}
render(){
return (
<input/>
)
}
}const ActionPanel = (props) => {
const escFunction = useCallback((event) => {
if (event.key === "Escape") {
//Do whatever when esc is pressed
}
}, []);
useEffect(() => {
document.addEventListener("keydown", escFunction, false);
return () => {
document.removeEventListener("keydown", escFunction, false);
};
}, [escFunction]);
return (
<input />
)
};Context
Stack Overflow Q#37440408, score: 357
Revisions (0)
No revisions yet.