Difficulty: Intermediate
Beyond click and change events, React provides handlers for a full range of keyboard and mouse interactions. Keyboard events are essential for building accessible interfaces, implementing shortcuts, and handling special keys. Mouse events enable hover effects, tooltips, drag interactions, and context menus. Understanding these events lets you build rich, interactive UIs.
Keyboard events in React include `onKeyDown` (fires when a key is pressed), `onKeyUp` (fires when a key is released), and `onKeyPress` (deprecated, do not use). The event object for keyboard events includes `event.key` (the key value like 'Enter', 'Escape', 'a'), `event.code` (the physical key like 'KeyA', 'Enter'), and modifier properties `event.ctrlKey`, `event.shiftKey`, `event.altKey`, and `event.metaKey` (Cmd on Mac). Always use `event.key` for logical key detection and `event.code` for physical key position.
Common keyboard patterns include detecting Enter to submit, Escape to close modals, and keyboard shortcuts like Ctrl+S to save. When implementing keyboard shortcuts, check modifier keys alongside the main key: `if (event.ctrlKey && event.key === 's') { event.preventDefault(); handleSave(); }`. The `preventDefault()` is important here to stop the browser's default Ctrl+S save dialog from appearing.
Mouse events include `onMouseEnter` and `onMouseLeave` (for hover effects without event bubbling), `onMouseOver` and `onMouseOut` (with bubbling), `onMouseDown` and `onMouseUp` (for press and release), and `onMouseMove` (for tracking position). The mouse event object includes `event.clientX` and `event.clientY` (coordinates relative to viewport), `event.pageX` and `event.pageY` (relative to document), and `event.button` (which mouse button was used).
React's event delegation simplifies event handling across many elements. Instead of attaching listeners to each list item, you can attach one listener to the parent and use `event.target` to determine which child was interacted with. This is efficient and scales well. While React handles delegation internally (attaching to the root), you can also leverage this pattern explicitly for dynamic lists where items are added and removed frequently.
function handleKeyDown(event) {
const key = event.key;
const mods = [];
if (event.ctrlKey) mods.push('Ctrl');
if (event.shiftKey) mods.push('Shift');
if (event.altKey) mods.push('Alt');
const combo = mods.length > 0 ? mods.join('+') + '+' + key : key;
console.log('Key: ' + combo);
}
// Simulate keyboard events
handleKeyDown({ key: 'Enter', ctrlKey: false, shiftKey: false, altKey: false });
handleKeyDown({ key: 's', ctrlKey: true, shiftKey: false, altKey: false });
handleKeyDown({ key: 'Escape', ctrlKey: false, shiftKey: false, altKey: false });
handleKeyDown({ key: 'Z', ctrlKey: true, shiftKey: true, altKey: false });
Keyboard events provide the key name and modifier states. Use these to implement keyboard shortcuts and handle special keys like Enter and Escape.
function handleMouseEnter(event) {
console.log('Mouse entered: ' + event.target.id);
}
function handleMouseLeave(event) {
console.log('Mouse left: ' + event.target.id);
}
function handleMouseMove(event) {
console.log('Position: (' + event.clientX + ', ' + event.clientY + ')');
}
// Simulate mouse interactions
handleMouseEnter({ target: { id: 'card-1' } });
handleMouseMove({ clientX: 150, clientY: 200 });
handleMouseMove({ clientX: 155, clientY: 205 });
handleMouseLeave({ target: { id: 'card-1' } });
onMouseEnter/Leave track hover state. onMouseMove provides real-time cursor coordinates for dynamic effects like tooltips or custom cursors.
// One handler on the parent handles clicks for all children
function handleListClick(event) {
const target = event.target;
if (target.dataset && target.dataset.action) {
const action = target.dataset.action;
const id = target.dataset.id;
console.log(action + ' item #' + id);
} else {
console.log('Clicked outside action area');
}
}
// Simulate clicking different items in a list
handleListClick({ target: { dataset: { action: 'edit', id: '1' } } });
handleListClick({ target: { dataset: { action: 'delete', id: '2' } } });
handleListClick({ target: { dataset: { action: 'view', id: '3' } } });
handleListClick({ target: { dataset: {} } });
Instead of attaching handlers to every item, one handler on the parent uses event.target data attributes to determine which item and action was triggered.
onKeyDown, onKeyUp, onMouseEnter, onMouseLeave, event delegation in React, keyboard accessibility