首页 > 解决方案 > keyDown 处理程序在自定义 React 钩子中被触发两次而不是一次

问题描述

我有以下钩子:

export default function useKeyPress(targetKey: string) {
    const [keyPressed, setKeyPressed] = useState(false);
    

    const downHandler = (e) => {
        if (e.repeat) {
            return;
        }

        if (e.key === targetKey) {
            console.log(targetKey);
            setKeyPressed(true);
        }
    }
    
    const upHandler = ({ key }) => {
        if (key === targetKey) {
            setKeyPressed(false);
        }
    }

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

    return keyPressed;
}

console.log(targetKey) 总是返回两次结果。即,如果我按 V,它将控制台记录它两次。

我正在尝试在我的 React 组件中实现一个函数调用,一旦 control + v 被击中,它就会调用一个函数。但问题是它调用了两次,因此不遵循规范。

我尝试使用 useState 布尔值来拦截第二次调用,但它没有奏效。

我以下列方式使用它:

    const pressedControl = useKeyPress('Control');
    const pressedV = useKeyPress('v');

useEffect(() => {
    if (pressedControl && pressedV) {
        console.log("Ctrl + V");
    }


}, [pressedC, pressedV]);

标签: javascriptreactjsevent-listenerkeydown

解决方案


它被触发两次的原因是因为我在一个组件内设置了挂钩,该组件是在一个迭代对象数组的映射函数中创建的。在这种情况下,我有 2 个对象,这意味着每个对象都触发了两次。我正在将逻辑移动到父组件。


推荐阅读