Event Handler Syntax
<button onClick={() => console.log('clicked')}>Click me</button>
function handleClick() {
console.log('clicked');
}
<button onClick={handleClick}>Click me</button>
<button onClick={(e) => handleClick(e, 'param')}>Click me</button>
Common Event Types
onClick, onDoubleClick, onMouseEnter, onMouseLeave
onMouseDown, onMouseUp, onMouseMove
onKeyDown, onKeyUp, onKeyPress
onChange, onSubmit, onFocus, onBlur, onInput
onTouchStart, onTouchEnd, onTouchMove
onCopy, onCut, onPaste
Event Object Properties
function handleClick(event) {
event.preventDefault();
event.stopPropagation();
console.log(event.target);
console.log(event.currentTarget);
console.log(event.type);
console.log(event.timeStamp);
}
Event Pooling (React 16 and earlier)
function handleClick(event) {
setTimeout(() => console.log(event.target), 100);
const target = event.target;
setTimeout(() => console.log(target), 100);
}
Controlled Components
function ControlledInput() {
const [value, setValue] = useState('');
const handleChange = (event) => {
setValue(event.target.value);
};
return (
<input
type="text"
value={value}
onChange={handleChange}
/>
);
}
Event Delegation
function ListWithDelegation() {
const handleClick = (event) => {
if (event.target.matches('li')) {
console.log('List item clicked:', event.target.textContent);
}
};
return (
<ul onClick={handleClick}>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
);
}
Conditional Event Handling
function ConditionalHandler({ isEnabled }) {
const handleClick = isEnabled ? () => console.log('enabled') : undefined;
return (
<button onClick={handleClick} disabled={!isEnabled}>
Click me
</button>
);
}
Custom Hooks for Events
function useEventListener(eventName, handler, element = window) {
useEffect(() => {
element.addEventListener(eventName, handler);
return () => element.removeEventListener(eventName, handler);
}, [eventName, handler, element]);
}
function Component() {
const handleKeyPress = useCallback((event) => {
if (event.key === 'Escape') {
console.log('Escape pressed');
}
}, []);
useEventListener('keydown', handleKeyPress);
return <div>Press Escape</div>;
}
Event Handler Optimization
function OptimizedComponent() {
const handleClick = useCallback((id) => {
console.log('Item clicked:', id);
}, []);
const handleSubmit = useCallback((event) => {
event.preventDefault();
}, []);
return (
<form onSubmit={handleSubmit}>
{items.map(item => (
<button key={item.id} onClick={() => handleClick(item.id)}>
{item.name}
</button>
))}
</form>
);
}
Debounced Event Handlers
function useDebounce(callback, delay) {
const timeoutRef = useRef();
return useCallback((...args) => {
clearTimeout(timeoutRef.current);
timeoutRef.current = setTimeout(() => callback(...args), delay);
}, [callback, delay]);
}
function SearchInput() {
const [query, setQuery] = useState('');
const debouncedSearch = useDebounce((searchTerm) => {
console.log('Searching for:', searchTerm);
}, 300);
const handleChange = (event) => {
const value = event.target.value;
setQuery(value);
debouncedSearch(value);
};
return <input value={query} onChange={handleChange} />;
}
Form Submission
function ContactForm() {
const handleSubmit = (event) => {
event.preventDefault();
const formData = new FormData(event.target);
const data = Object.fromEntries(formData);
console.log('Form data:', data);
};
return (
<form onSubmit={handleSubmit}>
<input name="name" type="text" required />
<input name="email" type="email" required />
<button type="submit">Submit</button>
</form>
);
}
Input Validation
function ValidatedInput() {
const [value, setValue] = useState('');
const [error, setError] = useState('');
const handleChange = (event) => {
const newValue = event.target.value;
setValue(newValue);
if (newValue.length < 3) {
setError('Must be at least 3 characters');
} else {
setError('');
}
};
return (
<div>
<input
value={value}
onChange={handleChange}
className={error ? 'error' : ''}
/>
{error && <span className="error-text">{error}</span>}
</div>
);
}
Keyboard Shortcuts
function KeyboardShortcuts() {
useEffect(() => {
const handleKeyDown = (event) => {
if ((event.ctrlKey || event.metaKey) && event.key === 's') {
event.preventDefault();
console.log('Save triggered');
}
if (event.key === 'Escape') {
console.log('Cancel triggered');
}
switch (event.key) {
case 'ArrowUp':
console.log('Navigate up');
break;
case 'ArrowDown':
console.log('Navigate down');
break;
}
};
document.addEventListener('keydown', handleKeyDown);
return () => document.removeEventListener('keydown', handleKeyDown);
}, []);
return <div>Use keyboard shortcuts</div>;
}
Focus Management
function FocusableComponent() {
const inputRef = useRef();
const handleKeyDown = (event) => {
if (event.key === 'Enter') {
inputRef.current.focus();
}
};
return (
<div onKeyDown={handleKeyDown}>
<button>Press Enter to focus input</button>
<input ref={inputRef} placeholder="This will be focused" />
</div>
);
}
Performance Optimization
const handleClick = useCallback(() => {
}, [dependencies]);
<ul onClick={handleListClick}>
{items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
<button onClick={() => handleClick(id)}>Click</button>
Accessibility
<div
onClick={handleClick}
onKeyDown={(e) => e.key === 'Enter' && handleClick()}
tabIndex={0}
role="button"
aria-label="Clickable element"
>
Click me
</div>
<button
onClick={handleClick}
aria-describedby="button-description"
>
Submit
</button>
<div id="button-description">Submits the form data</div>
Error Handling
function SafeEventHandler() {
const handleClick = (event) => {
try {
processEvent(event);
} catch (error) {
console.error('Event handling error:', error);
}
};
return <button onClick={handleClick}>Safe Click</button>;
}
Cleanup
function ComponentWithCleanup() {
useEffect(() => {
const handleResize = () => {
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return <div>Component with cleanup</div>;
}