检测Shift键是否按下React Native

3

我如何检测Shift键是否按下?我有一个文本输入框,当用户按下回车键时,如果他们当前没有按下回车键(与Facebook Messenger在桌面上的相同表单功能),我只想提交表单。

这是我的文本输入框:

<TextInput
    style={styles.input}
    placeholder={'Enter message'}
    onKeyPress={this.handleKeyPress}
/>

以下是处理程序:

handleMessageInputKeyPress(e) {
    if(e.nativeEvent.key == "Enter"){
        // Now check if the SHIFT key is currently pressed or not...
    }
}

1
e.nativeEvent.shiftKey? - Teemu
@Teemu 当我在if语句内添加console.log(e.nativeEvent.shiftKey);时,我得到了undefined - Leopold Joy
那么只需要检查 'Shift' 而不是 'Enter' 了吗?啊... Shift 没有触发 keypress ... - Teemu
@Teemu 但是我想要检查 Shift 键和 Enter 键是否同时按下,我该怎么做? - Leopold Joy
1
你需要另一个事件,比如 keydownkeyup,因为 keypress 不会被 SHIFT 触发,尽管 .shiftKey 仍然应该被定义。 - Teemu
@Teemu 所以我可以在 keydown 事件中记录 SHIFT 键被按下,然后在 keyup 事件中记录它被松开。然后当按下回车键时,我就可以检查同时是否也按下了 Shift 键。我会尝试这样做的,谢谢! - Leopold Joy
3个回答

5

您可以使用事件监听器来检测任何时候按下(或松开)键,然后过滤出您想要用作条件的键的结果。以下是使用钩子的示例:

  const [shiftHeld, setShiftHeld] = useState(false);


  function downHandler({key}) {
    if (key === 'Shift') {
      setShiftHeld(true);
    }
  }

  function upHandler({key}) {
    if (key === 'Shift') {
      setShiftHeld(false);
    }
  }

  useEffect(() => {
    window.addEventListener('keydown', downHandler);
    window.addEventListener('keyup', upHandler);
    return () => {
      window.removeEventListener('keydown', downHandler);
      window.removeEventListener('keyup', upHandler);
    };
  }, []);

这将根据Shift键是否按下将状态更改为true或false。然后,您可以在需要它的任何地方插入该值。 提示:您可以使用此格式来监听任何其他键。我很难找到关于这些键的名称的文档。如果您无法找到密钥名称,请在downHandler中的if语句之前记录key。

另外,请确保将侦听器留在useEffect中,否则您将会出现数据泄漏。


1

对于那些仍在寻找解决方案的人:

似乎由回调函数onKeyPress接收到的event具有以下属性:

enter image description here

看到它也有 ctrlKeyaltKey 很好。

因此解决方案如下:

<TextInput
    onKeyPress={event => {
        if (event.shiftKey && event.key === "Enter"){
            // ...
        }
    }} />

我没有看到这些标志,甚至文档也没有提到它们,你从哪里得到这些信息的? - Oscar Franco
onKeyPress事件没有接收上述标记。 - sameera madushan
2
这些标志仅在您使用 react-native-web 并在浏览器上运行时可用。 - Cù Đức Hiếu

0
创建一个像这样的钩子。
import React, {useEffect, useState} from "react";

const useKeyPress = (keyMap, callbackMap) => {
    const [keyPressed, setKeyPressed] = useState(new Set());

    const downHandler = (event) => {
      event.preventDefault();
      const { key, altKey, shiftKey, ctrlKey } = event;
  
      const modifiers = [];
      if (altKey) modifiers.push('alt');
      if (shiftKey) modifiers.push('shift');
      if (ctrlKey) modifiers.push('ctrl');
  
      // Generate all possible combinations of modifiers and key
      const combinations = [      [key.toLowerCase()],
        [modifiers.join('+'), key.toLowerCase()],
        [modifiers.reverse().join('+'), key.toLowerCase()]
      ];
  
      for (const combination of combinations) {
        const id = keyMap[combination.join('+')];
        const callback = callbackMap[id];
        if (callback) {
          const newKeyPressed = new Set(keyPressed);
          newKeyPressed.add(combination.join('+'));
          setKeyPressed(newKeyPressed);
          callback();
          break;
        }
      }
    };
  
    const upHandler = (event) => {
      event.preventDefault();
      const { key, altKey, shiftKey, ctrlKey } = event;
  
      const modifiers = [];
      if (altKey) modifiers.push('alt');
      if (shiftKey) modifiers.push('shift');
      if (ctrlKey) modifiers.push('ctrl');
  
      // Generate all possible combinations of modifiers and key
      const combinations = [      [key.toLowerCase()],
        [modifiers.join('+'), key.toLowerCase()],
        [modifiers.reverse().join('+'), key.toLowerCase()]
      ];
  
      for (const combination of combinations) {
        const id = keyMap[combination.join('+')];
        const callback = callbackMap[id];
        if (callback) {
          const newKeyPressed = new Set(keyPressed);
          newKeyPressed.delete(combination.join('+'));
          setKeyPressed(newKeyPressed);
          break;
        }
      }
    };
    
      
  
    useEffect(() => {
      window.addEventListener('keydown', downHandler);
      window.addEventListener('keyup', upHandler);
  
      return () => {
        window.removeEventListener('keydown', downHandler);
        window.removeEventListener('keyup', upHandler);
      };
    });
  
    return keyPressed;
  };

export default useKeyPress;
  

然后在您的其他组件中可以像这样使用它;

// Keyboard mappings
  const keyMap = {
    'ctrl+shift+p': 'preview',
  };
  const callbackMap = {
    'preview': () => setShowModal(prevModalVisible => !prevModalVisible),
  };
  useKeyPress(keyMap, callbackMap);

通过技巧,您可以映射任何您喜欢的三个键组合


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接