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

IT技术 javascript reactjs
2021-04-29 23:49:58

如何在 reactjs 上检测 Esc 按键?类似于 jquery

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

一旦检测到,我想将信息传递给组件。我有 3 个组件,其中最后一个活动组件需要对 Esc 按键做出react。

我在考虑一种在组件激活时进行注册

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

我相信这会奏效,但我认为它更像是回调。有没有更好的方法来处理这个问题?

4个回答

如果您正在寻找文档级键事件处理,那么在期间绑定它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/>
    )
  }
}

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

编辑:如果你使用钩子,你可以使用这个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 />
  )
};

你会想keyCodeReact 中SyntheticKeyBoardEvent 收听 escape 的(27) onKeyDown

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有助于查找其他键的键代码。

在功能组件中实现此目的的另一种方法是使用useEffect,如下所示:

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

您可以使用useState来触发某些内容,而不是 console.log

对于可重用的 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

用法:

const [isOpen, setIsOpen] = useState(false);
useEscape(() => setIsOpen(false))