Keyboard Events React
title: "Keyboard Events in React" weight: 15 description: "Learn how to handle keyboard events in React components for accessibility: onKeyDown for arrow navigation, Enter and Space for activation, Escape for dismissal, and proper keyboard event patterns for custom widgets." date: 2026-06-28 lastmod: 2026-06-28 tags: [accessibility, react]
Keyboard events in React require onKeyDown handlers for custom interactive components, supporting arrow key navigation for lists and menus, Enter and Space for activation, Escape for dismissal, and Home/End for boundary navigation.
## What You'll Learn
You will implement keyboard event handlers in React, follow ARIA keyboard patterns, handle focus movement with arrow keys, and support standard keyboard interactions for custom widgets.
## Why It Matters
Custom interactive components -- dropdowns, lists, sliders, tree views -- require explicit keyboard handling. React's event system makes this straightforward, but the patterns must follow platform conventions that users expect.
## Real-World Use
A listbox component allows arrow key navigation within the list, Enter to select an item, and Escape to close. Without these handlers, keyboard users cannot interact with the listbox at all.
## Keyboard Pattern Flow
```mermaid
flowchart TD
A[Keyboard Event] --> B{Which Key?}
B -->|ArrowUp/Down| C[Move focus in list]
B -->|Enter/Space| D[Activate/Select]
B -->|Escape| E[Dismiss/Close]
B -->|Home/End| F[First/Last item]
B -->|Tab| G[Next focusable element]
Implementing Keyboard Events
Follow ARIA authoring practices for keyboard patterns.
function Listbox({ items, selected, onSelect }) {
const listRef = useRef(null);
const [activeIndex, setActiveIndex] = useState(0);
const handleKeyDown = (e) => {
switch (e.key) {
case 'ArrowDown':
e.preventDefault();
setActiveIndex(prev => Math.min(prev + 1, items.length - 1));
break;
case 'ArrowUp':
e.preventDefault();
setActiveIndex(prev => Math.max(prev - 1, 0));
break;
case 'Home':
e.preventDefault();
setActiveIndex(0);
break;
case 'End':
e.preventDefault();
setActiveIndex(items.length - 1);
break;
case 'Enter':
case ' ':
e.preventDefault();
onSelect(items[activeIndex]);
break;
}
};
return (
<ul
ref={listRef}
role="listbox"
tabIndex={0}
onKeyDown={handleKeyDown}
aria-activedescendant={`option-${activeIndex}`}
>
{items.map((item, index) => (
<li
key={index}
id={`option-${index}`}
role="option"
aria-selected={selected === item}
className={activeIndex === index ? 'active' : ''}
>
{item}
</li>
))}
</ul>
);
}
// Slider with keyboard support
function Slider({ value, onChange, min = 0, max = 100 }) {
const handleKeyDown = (e) => {
switch (e.key) {
case 'ArrowRight':
case 'ArrowUp':
e.preventDefault();
onChange(Math.min(value + 1, max));
break;
case 'ArrowLeft':
case 'ArrowDown':
e.preventDefault();
onChange(Math.max(value - 1, min));
break;
case 'Home':
e.preventDefault();
onChange(min);
break;
case 'End':
e.preventDefault();
onChange(max);
break;
}
};
return (
<div
role="slider"
tabIndex={0}
aria-valuemin={min}
aria-valuemax={max}
aria-valuenow={value}
onKeyDown={handleKeyDown}
>
{value}
</div>
);
}
Common Mistakes
- Only handling onClick without keyboard alternatives
- Using onKeyPress instead of onKeyDown (onKeyPress is deprecated)
- Preventing default on Tab key (breaks navigation)
- Not managing focus movement with arrow keys
- Forgetting to add role and aria-* attributes alongside keyboard handlers
- Not supporting Home and End keys for list navigation
- Implementing keyboard handling without visual feedback
Practice and Challenge
Practice 1: Add arrow key navigation to a list component. Practice 2: Implement Escape key handling for a modal. Practice 3: Create a slider with keyboard support. Practice 4: Add keyboard handling to a menu button. Practice 5: Ensure Tab works correctly for leaving custom widgets.
Challenge: Build a complete keyboard-navigable widget in React: a combination of a search input with autocomplete suggestions. The autocomplete dropdown should support arrow up/down to navigate suggestions, Enter to select, Escape to close, and Tab to select and move to next field.
FAQ
Mini Project
Create a React keyboard navigation demo with four interactive widgets: listbox (arrow keys + Enter), slider (arrow keys + Home/End), menu button (Enter opens, arrows navigate, Escape closes), and modal (Escape closes, focus trap). Each widget should follow ARIA authoring practices.
What's Next
Form Accessibility in React covers accessible form patterns in React.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro