0

I have the following hook:

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

The console.log(targetKey) always returns the result twice. I.e if I hit V, it will console log it twice.

I am trying to implement a function call in my React component that calls a function once control + v is hit. But the issue is that it calls it twice, thus not following specification.

I've tried using useState booleans to intercept a second call but it hasn't worked.

I use it in the following manner:

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

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


}, [pressedC, pressedV]);
3
  • Have you tried adding e.preventDefault() on the first line within your downHandler function? Commented Mar 18, 2021 at 20:54
  • 1
    I would think it runs your event twice because you're listening to keydown and keyup which fires both when someone clicks a key ... also you're adding your events twice for both control and v keys Commented Mar 18, 2021 at 20:56
  • I checked with only 1 instance of a hook called "pressedA". The down handler is fired twice, and so is the up handler. Commented Mar 19, 2021 at 6:03

1 Answer 1

1

The reason why it was being fired twice was because I set up the hooks inside a component that is created in a map function which iterates an array of objects. In this case, I had 2 objects, meaning it fired twice for each. I'm moving the logic to a parent component.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.