Instantly share code, notes, and snippets.

Embed
What would you like to do?
import { useState, useEffect } from 'react';
// Usage
function App() {
// Call our hook for each key that we'd like to monitor
const happyPress = useKeyPress('h');
const sadPress = useKeyPress('s');
const robotPress = useKeyPress('r');
const foxPress = useKeyPress('f');
return (
<div>
<div>h, s, r, f</div>
<div>
{happyPress && '😊'}
{sadPress && '😢'}
{robotPress && '🤖'}
{foxPress && '🦊'}
</div>
</div>
);
}
// Hook
function useKeyPress(targetKey) {
// State for keeping track of whether key is pressed
const [keyPressed, setKeyPressed] = useState(false);
// If pressed key is our target key then set to true
function downHandler({ key }) {
if (key === targetKey) {
setKeyPressed(true);
}
}
// If released key is our target key then set to false
const upHandler = ({ key }) => {
if (key === targetKey) {
setKeyPressed(false);
}
};
// Add event listeners
useEffect(() => {
window.addEventListener('keydown', downHandler);
window.addEventListener('keyup', upHandler);
// Remove event listeners on cleanup
return () => {
window.removeEventListener('keydown', downHandler);
window.removeEventListener('keyup', upHandler);
};
}, []); // Empty array ensures that effect is only run on mount and unmount
return keyPressed;
}
@awnigharbia

This comment has been minimized.

Copy link

awnigharbia commented Nov 16, 2018

import React, { useState, useEffect } from "react";

export default function useKeyPress(targetKey) {
  // State for keeping track of whether key is pressed
  const [keyPressed, setKeyPressed] = useState(false);
  let prevKey = "";

  // If pressed key is our target key then set to true
  function downHandler({ key }) {
    // checking keep pressing re-rendering
    if (prevKey === targetKey) return;

    if (key === targetKey) {
      setKeyPressed(true);
      prevKey = key;
    }
  }

  // If released key is our target key then set to false
  const upHandler = ({ key }) => {
    if (key === targetKey) {
      setKeyPressed(false);
      prevKey = "";
    }
  };
  // Add event listeners
  useEffect(() => {
    window.addEventListener("keydown", downHandler);
    window.addEventListener("keyup", upHandler);
    // Remove event listeners on cleanup
    return () => {
      window.removeEventListener("keydown", downHandler);
      window.removeEventListener("keyup", upHandler);
    };
  }, []); // Empty array ensures that effect is only run on mount and unmount

  return keyPressed;
}

I suggest checking the long pressing for the key itself so it prevents it from re-reding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment