如何在 React 中检测 Esc 按键以及如何处理它

2022-08-30 01:44:20

如何检测 reactjs 上的 Esc 按键?与jquery类似的东西

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

一旦检测到,我想传递信息组件。我有3个组件,其中最后一个活动组件需要对逃生键做出反应。

我正在考虑当组件变为活动状态时进行一种注册

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>
    )
  }
}

和所有组件

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)}/>
    )
  }
}

我相信这会起作用,但我认为它更像是一个回调。有没有更好的方法来解决这个问题?


答案 1

如果你正在寻找一个文档级的键事件处理,那么在过程中绑定它是最好的方法(如 Brad Colthurst 的 codepen 示例所示):componentDidMount

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/>
    )
  }
}

请注意,应确保在卸载时删除密钥事件侦听器,以防止潜在的错误和内存泄漏。

编辑:如果您使用的是钩子,则可以使用此结构来产生类似的效果:useEffect

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);
    };
  }, []);

  return (   
    <input />
  )
};

React 17 的 EDIT:React 改变了文档级事件绑定的处理方式,如果在链中的某个点被调用,这可能会导致此实现停止工作。通过将侦听器的最后一个参数更改为 而不是 ,可以确保首先调用此函数。如果您这样做并同时调用 ,则以前调用的其他处理程序将不再发生,因此我建议尽可能避免该调用。event.stopPropogation()truefalseevent.stopPropogation()


答案 2

你会想听听 React SyntheticKeyBoardEvent 的 escape 's (27):keyCodeonKeyDown

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在问题评论中发布的CodePen有助于查找其他密钥的关键代码。