Using onKeyDown on a certain element will require focus to work as intended.
We can make your MdOutlinePause component focus-able by adding the tabindex attribute. That will allow you to give the icon focus by hitting tab or by clicking on it. The element would look something like this:
<MdOutlinePause tabIndex={0} onKeyDown={handleKey} />
If you want to detect the key event without having to focus the element, you will need to attach an event listener. We can do this with useEffect so this happens onMount, and we'll attach the event listener to the window so it works regardless of which element has focus:
/// Don't copy and paste this - see below
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
});
}, []);
/// Don't copy and paste this - see below
This allows you to detect the keyboard event, which is great, but there's an issue: the eventListener gets added again whenever the page mounts, but is never removed. So you will likely run into issues of your function getting called multiple times on each keyPress.
We can fix this by removing the event listener in the return from useEffect. This is how we specify a function to let the useEffect clean up after itself. This ensures that our useEffect is never adding more than one "keydown" event listener at a time:
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, []);
Here's a full example on codesandbox
This works great if you don't need to access state in your handleKeyPress function.
It is a common use case to need to do something with state variables when the user does a certain action, and if we need to access updated state then we run into a problem: we attached handleKeyPress to the event listener onMount and the function never gets updated, so it will always use the initial version of state. This codesandbox illustrates the issue.
We can fix this by adding handleKeyPress to the dependencies array for useEffect, but this results in our event listener being removed and re-added on every render since handleKeyPress will be updated on each render. A better solution is to use the callback pattern with our handleKeyPress so that it is only updated when actually necessary (when the state it depends on is updated). We also want to add handleKeyPress to our useEffect dependency array so we create a new event listener when the handleKeyPress function changes:
const handleKeyPress = useCallback((event) => {
// do stuff with stateVariable and event
}, [stateVariable]);
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, [handleKeyPress]);
Now everything updates appropriately! Here's a full example of this on codesandbox.
There's one more solution which lets you access state in the simplest way possible. The downside is that the only state variable you have access to (with updated values) will be the state variable you are updating, so this solution is situational. To access other state variables, you'll have to use the solution above.
By passing a function to useState, we can access the previous state as the first argument of the function. This allows for a much simpler approach, shown below and in this codesandbox.
const [text, setText] = useState("");
const handleKeyPress = event => {
setText(previousText => `${previousText}${event.key}`);
};
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, []);
Answer from Andrew Hulterstrom on Stack OverflowFiring a button onKeyUp?
I can't catch the JavaScript keyup event of the Input element and call Search method in the HomeController. Net Core 6.
How to trigger "Tab" keyboard key click from the code
React & Redux: Adding a Handler for 'Enter Key' Events
Videos
Currently have a button that I want to fire using the Enter key in a class component but for some reason it's not working. Any ideas?
handleKeyUp(event) {
if (event.keyCode === 13) {
console.log('Enter key has been pressed')
}
}
render() {
return(
<div>
<button
onKeyUp={ this.handleKeyUp }
>
Submit
</button>
</div>
);
}Also the url in the ajax call does not support ~/. You need to use razor syntax to generate, or the best sotionis to set the base href in html
Your HTML is malformed (your GetKey function call is using double quotes inside double quotes). That is causing issues potentially but since you're using Razor I haven't tested it. Your initial function is trying to hook up the event before the element is even defined so that would fail as well. The browser's console window should be showing you errors for these.
Here's the simplest equivalent code to do what you want.
-
Search