简体   繁体   English

如何检测 React 中的 Esc 键按下以及如何处理

[英]How to detect Esc Key Press in React and how to handle it

How do I detect Esc keypress on reactjs?如何检测 reactjs 上的 Esc 按键? The similar thing to jquery类似于 jquery

$(document).keyup(function(e) {
     if (e.keyCode == 27) { // escape key maps to keycode `27`
        // <DO YOUR WORK HERE>
    }
});

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.我有 3 个组件,其中最后一个活动组件需要对退出键做出反应。

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 (
      <div class="root">
        <ActionPanel onActive={this.onActive.bind(this)}/>
        <DataPanel onActive={this.onActive.bind(this)}/>
        <ResultPanel onActive={this.onActive.bind(this)}/>
      </div>
    )
  }
}

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 (   
      <input onKeyDown={this.onActive.bind(this)}/>
    )
  }
}

I believe this will work but I think it will be more like a callback.我相信这会奏效,但我认为它更像是回调。 Is there any better way to handle this?有没有更好的方法来处理这个问题?

If you're looking for a document-level key event handling, then binding it during componentDidMount is the best way (as shown by Brad Colthurst's codepen example ): 如果您正在寻找文档级的键事件处理,那么在componentDidMount期间绑定它是最好的方法(如Brad Colthurst的codepen示例所示 ):

class ActionPanel extends React.Component {
  constructor(props){
    super(props);
    this.escFunction = this.escFunction.bind(this);
  }
  escFunction(event){
    if(event.keyCode === 27) {
      //Do whatever when esc is pressed
    }
  }
  componentDidMount(){
    document.addEventListener("keydown", this.escFunction, false);
  }
  componentWillUnmount(){
    document.removeEventListener("keydown", this.escFunction, false);
  }
  render(){
    return (   
      <input/>
    )
  }
}

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: 编辑:如果您正在使用挂钩,则可以使用此useEffect结构产生类似的效果:

const ActionPanel = (props) => {
  const escFunction = useCallback((event) => {
    if(event.keyCode === 27) {
      //Do whatever when esc is pressed
    }
  }, []);

  useEffect(() => {
    document.addEventListener("keydown", escFunction, false);

    return () => {
      document.removeEventListener("keydown", escFunction, false);
    };
  }, []);

  return (   
    <input />
  )
};

For a reusable React hook solution对于可重用的 React 钩子解决方案

import React, { useEffect } from 'react';

const useEscape = (onEscape) => {
    useEffect(() => {
        const handleEsc = (event) => {
            if (event.keyCode === 27) 
                onEscape();
        };
        window.addEventListener('keydown', handleEsc);

        return () => {
            window.removeEventListener('keydown', handleEsc);
        };
    }, []);
}

export default useEscape

You'll want to listen for escape's keyCode (27) from the React SyntheticKeyBoardEvent onKeyDown : 您将需要从React SyntheticKeyBoardEvent onKeyDown监听转义的keyCode (27):

const EscapeListen = React.createClass({
  handleKeyDown: function(e) {
    if (e.keyCode === 27) {
      console.log('You pressed the escape key!')
    }
  },

  render: function() {
    return (
      <input type='text'
             onKeyDown={this.handleKeyDown} />
    )
  }
})

Brad Colthurst's CodePen posted in the question's comments is helpful for finding key codes for other keys. 问题注释中张贴的Brad Colthurst的CodePen有助于查找其他按键的按键代码。

React uses SyntheticKeyboardEvent to wrap native browser event and this Synthetic event provides named key attribute , React使用SyntheticKeyboardEvent包装本地浏览器事件,并且此Synthetic事件提供了命名的key属性
which you can use like this: 您可以这样使用:

handleOnKeyDown = (e) => {
  if (['Enter', 'ArrowRight', 'Tab'].includes(e.key)) {
    // select item
    e.preventDefault();
  } else if (e.key === 'ArrowUp') {
    // go to top item
    e.preventDefault();
  } else if (e.key === 'ArrowDown') {
    // go to bottom item
    e.preventDefault();
  } else if (e.key === 'Escape') {
    // escape
    e.preventDefault();
  }
};

Another way to accomplish this in a functional component, is to use useEffect and useFunction , like this: 在功能组件中完成此操作的另一种方法是使用useEffectuseFunction ,如下所示:

import React, { useEffect } from 'react';

const App = () => {


  useEffect(() => {
    const handleEsc = (event) => {
       if (event.keyCode === 27) {
        console.log('Close')
      }
    };
    window.addEventListener('keydown', handleEsc);

    return () => {
      window.removeEventListener('keydown', handleEsc);
    };
  }, []);

  return(<p>Press ESC to console log "Close"</p>);
}

Instead of console.log, you can use useState to trigger something. 您可以使用useState来触发某些操作,而不是console.log。

function handleEsc(event) {
    if (event.keyCode === 27) {
      close();
    }
  }

  useEffect(() => {
    window.addEventListener("keydown", handleEsc);
    return () => {
      window.removeEventListener("keydown", handleEsc);
    };
  }, []);

If you want to make this work directly in your component instead of a hook, or if like me you are using this in a hook that DOES NOT return a <Component this worked for me.如果您想直接在您的组件中而不是钩子中使其工作,或者如果您像我一样在不返回 <Component 的钩子中使用它,这对我有用。

useEffect(()=>{
    document.addEventListener('keydown', (e) => {
      e.key === 'Escape' && setOpenState(false)
    })
    return () => {
      document.removeEventListener('keydown', (e) => e)
    }
  },[openState])

React Hook反应钩子

const [add, setAdd] = useState(false);
useEffect(()=>{
        document.addEventListener("keydown", keydownFunction, false);
        return  () => { document.removeEventListener("keydown", keydownFunction, false); };
    }, []);
const keydownFunction =(event)=>{
        if (event.key === "Escape") {  setAdd(false); }
        if (event.key === "+") { setAdd(true); }) }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM