Leveraging the ReactJS Hook useState for detecting Key press events

As I am in the process of constructing a piano, I want it to showcase certain CSS styles when the user "presses" specific keyboard buttons (via keydown event) - even enabling the simultaneous clicking of multiple different buttons. Once the user releases the keys (using keyup event), the corresponding CSS styles should be removed.

For example, holding down the "A", "B", and "C" keys will add an active class to each of them, whereas releasing just the "C" key would remove the active class from that particular key.

I intend to achieve this using a react hook implementation like so:


const [press, setPress] = useState([]); // Hook state

// Store the user's keyboard clicks in an array
const keyDown = (e) => {
    if (e.repeat) {
        return;
    }
    setPress((oldArr) => [...oldArr, e.key]);
};

// Remove only the released key
const keyUp = (e) => {
    const keyRemove = press.filter((key) => key !== e.key);
    setPress(keyRemove);
};

// Add key press event listener
useEffect(() => {
    window.addEventListener("keydown", keyDown);
    window.addEventListener("keyup", keyUp);
    return function cleanup() {
      window.removeEventListener("keydown", keyDown);
      window.removeEventListener("keyup", keyUp);
    };
  }, []);

// Pass the press array to child element
return (
    <div className="main">
        <Child press={press} /> 
    </div>
);

The keydown event is functioning correctly, but the keyup event keeps resetting the press array back to empty. I'm puzzled about why this behavior occurs in this manner. Could someone please provide an explanation? Thank you in advance!

Answer №1

It appears that the issue lies within your logic for the keyUp function. It seems like you need to make sure to properly update the filter:

const keyUp = (e) => {
  setPress(press.filter((key) => key !== e.key));
};

Answer №2

I found success by adjusting the key filter up.

const newKey = press.filter(function(item, idx, array){ 
        return item !== e.key;
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Enable smooth horizontal scrolling of Mui TabList when dragging items using react-beautiful-dnd

I recently incorporated Drag & Drop functionality into my Mui TabList using react-beautiful-dnd. While the drag and drop feature works smoothly, I encountered an issue with implementing auto-scroll for horizontal tab lists when there are too many tabs to d ...

Encountering ENOENT error when accessing view file in NodeJS and Express

I've encountered a strange issue with my nodeJS application after refactoring it. The app launches without any problems, the API responds correctly. However, when I attempt to access "/", I receive the following error: Error: ENOENT, stat '/view ...

What's the best way to ensure uniform card height in Material-UI?

Is there a way to ensure consistent card height in Material-UI without setting a fixed height? I want the card heights to dynamically adjust based on content, with all cards matching the tallest one on the website. How can this be achieved while also addin ...

How to create a donut chart in Highcharts without an inner pie section?

I've been scouring the internet in search of a solution to create a basic donut chart using the Highcharts library. Most examples I come across show donut charts with both an inner pie and outer donut (see here). Is there a way to remove the inner pi ...

What is the best way to assign an identifier to a variable in this scenario?

script.js $('a').click(function(){ var page = $(this).attr('href'); $("#content").load(page); return false; }); main.html <nav> <a href="home.html">Home</a> <a href="about.html">About</a> < ...

State dropdown in Angular dynamically updates based on the country selected

I am in search of a contextual state dropdown menu that is linked to the country, ensuring only relevant states are displayed. I have explored these two solutions for guidance in my project. Angularjs trigger country state dependency angularjs dependant ...

Manipulating object properties within an array through iteration

Here is the array I am working with: var data = [ {"firstname":"A","middlename":"B","lastname":"C"}, {"firstname":"L","middlename":"M","lastname":"N"}, {"firstname":"X","middlename":"Y","lastname":"Z"} ]; I need to update the values for all keys - firstn ...

Can you explain the purpose of the statement `var MyConstructor = function MyConstructor()`?

Can you explain the distinction between these two code snippets: var NodestrapGenerator = module.exports = function NodestrapGenerator() { yeoman.generators.Base.apply(this, arguments); // more code here }; and: var NodestrapGenerator = module.expor ...

Exploring the possibilities of jQuery with Accordion functionality and creating dynamic multiple menus

Incorporating the Wayfinder and Accordion menus, I have set up a two-level menu structure for the left column. The structure looks like this: <ul class="accordion">: Menu 1 Sub-menu 1.1 Sub-menu 1.2 Sub-menu 1.3 Menu 2 Sub-menu 2 ...

Font Awesome symbols using the class "fa-brands" are not functioning as expected

I have included a font awesome library in the header using the following code: <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> However, when I try to display an ic ...

Leveraging split and map functions within JSX code

const array = ['name', 'contact number'] const Application = () => ( <div style={styles}> Unable to display Add name & contact, encountering issues with splitting the array). </div> ); I'm facing difficul ...

Chrome Extension: Sending Data from Panel Window to Popup - A Step-by-Step Guide

I've been developing a Chrome extension that displays a window (popup.html) containing a button for playing videos when the extension icon is clicked. Upon clicking the play button, another window created using window.create of type panel opens up. Th ...

A collaborative effort on Facebook, Twitter, and GooglePlus involves generating SCRIPT tags collectively

If you're familiar with the javascripts used by platforms like Facebook, Twitter, and Google Plus, you'll recognize them below. Here, I've simply organized them neatly together. How can I utilize jQuery to create the script tags and optimiz ...

Customizing the Border Color in material-ui

I'm attempting to apply the border-top and border-bottom styles to the <Box> component in Material UI while using React. After referencing the official documentation at https://material-ui.com/system/borders/ I inserted the following code int ...

struggling with managing an array of Vue3 refs

Having an issue with handling vue3 refs, specifically when retrieving data from Firestore. When logging the [documents], everything seems to work fine. However, I run into errors when trying to access values from an array within a document. For example, ...

The stylesheet reference, <link rel="stylesheet" href="../css/style.css">, appears to be malfunctioning

My project structure includes css files in a folder named css and jsp files in a folder named jsp, both located inside the WEB-INF folder. I am wondering how to access the css file within a jsp file. <link rel="stylesheet" href="../css/style.css> T ...

Would mobx-react-lite be a suitable option for handling state in a sprawling React application?

Is mobx a better option than redux for managing state in large enterprise applications? While it may be easier to learn and apply, are there any potential drawbacks or blocking issues? If you have experience using mobx-react-lite in an enterprise setting, ...

Using identical CSS for two separate layouts

Imagine having to work with an html page that cannot be altered in any way. The only tool at your disposal is CSS. The page is loaded and shown through an iframe from a different domain. This particular page serves as a payment gateway, displaying either ...

Removing Form Fields Utilizing Javascript

Is it possible to create a unique function in Javascript that automatically removes a form field if it remains unfilled? <form id="myform"> <label for="q1" id="q1label">question 1</label> <input type="text" id="q1" name="q1"/> < ...

Is there anyone who has successfully integrated column selection and highlighting features into the MUI Data Grid?

Seeking advice on how to incorporate "column selection" or "highlighting" functionality using the MUI DataGrid. The goal is to allow users to click on a column and have it highlighted. Has anyone successfully implemented this feature? ...