React Keyboard Events
Table of Contents + −
In the last lesson you learned about React Form Events, so you can read what a user types. This lesson is about catching key presses like Enter and Escape, so you can run an action the moment a specific key goes down.
🤔 Why do we need keyboard events?
Here’s the pain. Users expect keys to do things, and a form with only a button feels broken to them.
- You build a search box. The user types a query, then presses Enter like they always do.
- Nothing happens. They have to move the mouse and click a button instead. Annoying, right?
- Or you open a popup. The user hits Escape to close it, because that’s the normal way. But your popup just sits there.
- These are small things, but they make an app feel slow and clumsy.
So the real problem is that people want to drive your app with the keyboard. Keyboard events let your component listen for key presses and react to them.
🧩 What are keyboard events?
A keyboard event is a signal React fires when the user presses or releases a key while an element is focused.
- A keyboard event is just React telling you “a key was pressed” along with details about which key it was.
- You listen for it with a prop like
onKeyDown, the same way you usedonClick. - React hands your function an event object, usually called
e. Inside it is everything you need to know about the press. - The most useful piece is
e.key. It holds the name of the key that was pressed, as text.
Think of it like a doorbell. When someone presses a key, the bell rings, and the event object is the note that says exactly which button they pushed.
⌨️ onKeyDown and onKeyUp
There are two main moments you can listen for. One is when the key goes down, the other is when it comes back up.
onKeyDownfires the instant a key is pressed down. This is the one you’ll use most of the time.onKeyUpfires when the key is released. Useful when you care about the press ending, not starting.- For most actions like “submit on Enter”,
onKeyDownis the right choice because it reacts immediately.
This input logs which key was pressed the moment it goes down.
function KeyLogger() { const handleKeyDown = (e) => { console.log("You pressed:", e.key); };
return <input type="text" onKeyDown={handleKeyDown} />;}When you press the “a” key, e.key is "a". Press Enter and e.key is "Enter". Press Escape and it’s "Escape". So e.key gives you a plain, readable name for whatever was pressed.
onKeyPress is gone
You may see older code using onKeyPress. That one is deprecated, which means
it’s old and you should not use it. Stick with onKeyDown and onKeyUp in
modern React.
🔑 Reading e.key the right way
Now the important part. To know which key was pressed, read e.key, not old number codes.
e.keyis a readable string like"Enter","Escape","a", or"ArrowUp". Easy to understand at a glance.- Older code used
e.keyCode, a number like13for Enter. Nobody remembers what13means, andkeyCodeis deprecated too. - So always compare against the readable name. Check
e.key === "Enter", nevere.keyCode === 13.
This shows the old number-code way versus the modern e.key way.
const handleKeyDown = (e) => { // ❌ Old and deprecated - what is 13 even? if (e.keyCode === 13) { console.log("Enter pressed"); }
// ✅ Modern and clear - reads like English if (e.key === "Enter") { console.log("Enter pressed"); }};Both versions try to detect Enter, but only the e.key one is correct for modern React. It reads like plain English, so anyone can tell what it checks.
🔎 Submit a search when Enter is pressed
Let’s build the real thing now. A search box that runs a search the moment the user presses Enter.
This input keeps its text in state, and presses Enter to fire the search.
import { useState } from "react";
function SearchBox() { const [query, setQuery] = useState("");
const handleKeyDown = (e) => { if (e.key === "Enter") { console.log("Searching for:", query); } };
return ( <input type="text" value={query} onChange={(e) => setQuery(e.target.value)} onKeyDown={handleKeyDown} placeholder="Search and press Enter" /> );}Let’s walk through what happens here.
useState("")holds the current text of the input inquery, starting empty.onChangeupdatesqueryon every keystroke, so state always matches what’s typed.onKeyDownrunshandleKeyDownon every key press.- Inside it,
if (e.key === "Enter")checks for just the Enter key. Other keys are ignored. - When Enter is pressed, you run your search using the current
query.
Output
Searching for: react keyboard eventsSo the user types, hits Enter, and the search fires. No button click needed. That’s exactly the behaviour people expect.
🚪 Close a box when Escape is pressed
Same idea, different key. A common pattern is closing a popup when the user presses Escape.
This box shows when open, and Escape closes it.
import { useState } from "react";
function Popup() { const [isOpen, setIsOpen] = useState(true);
const handleKeyDown = (e) => { if (e.key === "Escape") { setIsOpen(false); } };
if (!isOpen) return null;
return ( <input type="text" onKeyDown={handleKeyDown} placeholder="Press Escape to close" /> );}Here’s the flow.
isOpenstarts astrue, so the box shows on screen.onKeyDowncheckse.key === "Escape"on every key press.- When Escape is pressed,
setIsOpen(false)flips the state to closed. if (!isOpen) return nullthen renders nothing, so the box disappears.
So one key press closes the box. The user gets the Escape behaviour they’re used to from every other app.
🎯 Keyboard events need focus
One thing trips people up here, so let’s be clear about it. Keyboard events only fire on the element that has focus.
- An element has focus when it’s the active target for typing, like an input you clicked into.
- Inputs, textareas, and buttons can take focus by default, so they catch keyboard events naturally.
- A plain
<div>cannot take focus on its own, so by default it never hears key presses. - To make a
<div>focusable, give ittabIndex={0}. Now it can be focused and it will fire keyboard events.
This div can take focus and listen for keys because of tabIndex.
function Panel() { const handleKeyDown = (e) => { if (e.key === "Escape") { console.log("Escape pressed inside the panel"); } };
return ( <div tabIndex={0} onKeyDown={handleKeyDown}> Click me first, then press Escape </div> );}Here’s why this works.
tabIndex={0}is what makes the div focusable in the first place.- Without it, you’d click the div and press Escape, and nothing would happen.
- That’s because the div never had focus to begin with, so it never heard the key.
Focus first, then keys
If your keyboard handler “isn’t working”, check focus first. The element must
be focused before it hears any key press. For a <div>, that almost always
means you forgot tabIndex={0}.
🧩 What You’ve Learned
- ✅ Keyboard events let your component react to key presses like Enter and Escape
- ✅
onKeyDownfires when a key goes down,onKeyUpfires when it’s released - ✅
onKeyPressis deprecated, so useonKeyDownandonKeyUpinstead - ✅ Read
e.keyto get a readable name like"Enter","Escape", or"a" - ✅ Use
e.key === "Enter", never the old deprecatede.keyCode === 13 - ✅ A common pattern is submitting a search on Enter or closing a box on Escape
- ✅ Keyboard events only fire on focused elements, and a
<div>needstabIndex={0}to take focus
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
Which property tells you which key was pressed in a modern React keyboard event?
Why: e.key holds a readable name like "Enter" or "Escape". e.keyCode is the old, deprecated number-based way and should not be used in modern React.
- 2
How do you check if the user pressed the Enter key?
Why: Compare e.key against the readable name "Enter". The keyCode === 13 form is deprecated and harder to read.
- 3
What is the status of onKeyPress in modern React?
Why: onKeyPress is deprecated. Use onKeyDown for immediate reactions and onKeyUp for when a key is released.
- 4
Why might a keyboard handler on a plain <div> never fire?
Why: Keyboard events only fire on the focused element. A plain div cannot take focus by default, so adding tabIndex={0} makes it focusable and able to hear key presses.
🚀 What’s Next?
Now you can catch key presses and react to the exact key, like submitting on Enter or closing on Escape. Next you’ll handle the other big source of user input: the mouse, with clicks, hovers, and more.