Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
openaec-foundation avatar

React Syntax Events

  • 11 installs
  • 6 repo stars
  • Updated July 8, 2026
  • openaec-foundation/react-claude-skill-package

Helps with frontend development tasks.

About

react-syntax-events is a Claude Code skill for frontend development. It helps solo builders move faster with AI-assisted development.

  • react-syntax-events
  • Frontend Development
  • AI-coding skill

React Syntax Events by the numbers

  • 11 all-time installs (skills.sh)
  • Ranked #1,658 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/openaec-foundation/react-claude-skill-package --skill react-syntax-events

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs11
repo stars6
Last updatedJuly 8, 2026
Repositoryopenaec-foundation/react-claude-skill-package

What it does

Helps with frontend development tasks.

Files

SKILL.mdMarkdownGitHub ↗

react-syntax-events

Quick Reference

Synthetic Event System

React wraps all native browser events in SyntheticEvent objects. These wrappers normalize cross-browser differences and provide a consistent API.

ConceptDetail
WrapperEvery handler receives a SyntheticEvent, NOT a native Event
DelegationReact attaches ONE listener to the root container, NOT to individual DOM nodes
PoolingReact 17+ does NOT pool events -- accessing e in async callbacks is safe
Native accessUse e.nativeEvent to access the underlying browser event

TypeScript Event Types

React TypeNative EquivalentCommon Elements
React.MouseEvent<T>MouseEventHTMLButtonElement, HTMLDivElement
React.ChangeEvent<T>EventHTMLInputElement, HTMLSelectElement, HTMLTextAreaElement
React.FormEvent<T>EventHTMLFormElement
React.KeyboardEvent<T>KeyboardEventHTMLInputElement, HTMLDivElement
React.FocusEvent<T>FocusEventHTMLInputElement, HTMLButtonElement
React.DragEvent<T>DragEventHTMLDivElement, HTMLImageElement
React.TouchEvent<T>TouchEventHTMLDivElement, HTMLButtonElement
React.ClipboardEvent<T>ClipboardEventHTMLInputElement, HTMLDivElement
React.WheelEvent<T>WheelEventHTMLDivElement, HTMLElement
React.PointerEvent<T>PointerEventHTMLDivElement, HTMLButtonElement

The generic parameter T specifies the element the handler is attached to. ALWAYS provide it for correct e.currentTarget typing.

Critical Warnings

NEVER use onKeyPress -- it is deprecated. ALWAYS use onKeyDown or onKeyUp instead.

NEVER type event handlers as (e: any) => void -- ALWAYS use the specific React event type with the correct element generic.

NEVER call e.stopPropagation() as a default habit -- it breaks parent listeners, analytics tools, and modal close handlers. ONLY use it when you have a specific reason.

ALWAYS call e.preventDefault() in onSubmit handlers to prevent full page reload.

ALWAYS provide the element generic parameter (e.g., <HTMLInputElement>) -- without it, e.currentTarget is typed as HTMLElement and you lose access to element-specific properties like .value.

NEVER read e.currentTarget inside async/await or setTimeout -- currentTarget is set to null after the event handler returns. Extract the value synchronously first.

---

Event Handler Typing Patterns

Inline Handler

<button onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
  console.log(e.currentTarget.disabled);
}}>
  Click
</button>

Extracted Handler

const handleClick = (e: React.MouseEvent<HTMLButtonElement>): void => {
  console.log(e.currentTarget.disabled);
};

<button onClick={handleClick}>Click</button>

Handler as Props

interface ButtonProps {
  onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
  onFocus?: (e: React.FocusEvent<HTMLButtonElement>) => void;
}

const Button = ({ onClick, onFocus }: ButtonProps): JSX.Element => (
  <button onClick={onClick} onFocus={onFocus}>Click</button>
);

React.EventHandler Type

React provides shorthand types for handler props:

interface Props {
  onClick: React.MouseEventHandler<HTMLButtonElement>;
  onChange: React.ChangeEventHandler<HTMLInputElement>;
  onSubmit: React.FormEventHandler<HTMLFormElement>;
  onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;
}

These are equivalent to (e: React.MouseEvent<HTMLButtonElement>) => void, etc.

---

Passing Data to Handlers

Arrow Function (Preferred)

const handleDelete = (id: string, e: React.MouseEvent<HTMLButtonElement>): void => {
  e.stopPropagation();
  deleteItem(id);
};

{items.map((item) => (
  <button key={item.id} onClick={(e) => handleDelete(item.id, e)}>
    Delete {item.name}
  </button>
))}

Currying Pattern

const handleAction = (id: string) => (e: React.MouseEvent<HTMLButtonElement>): void => {
  e.preventDefault();
  performAction(id);
};

<button onClick={handleAction(item.id)}>Act</button>

NEVER use .bind(this, arg) in function components -- it creates a new function reference every render just like arrow functions, but with worse readability.

---

stopPropagation vs preventDefault

MethodPurposeUse When
e.preventDefault()Prevents the browser default actionForm submit, link navigation, drag default behavior
e.stopPropagation()Stops the event from reaching parent handlersNested clickable elements, preventing parent dismissals

Decision Tree

1. Is the browser doing something unwanted (page reload, navigation)? --> preventDefault() 2. Is a parent handler firing when it should not? --> stopPropagation() 3. Both? --> Call both explicitly

const handleLinkClick = (e: React.MouseEvent<HTMLAnchorElement>): void => {
  e.preventDefault();  // stop navigation
  e.stopPropagation(); // stop parent onClick
  openModal();
};

---

Capture Phase

React supports capture-phase listeners by appending Capture to any event prop:

<div onClickCapture={(e: React.MouseEvent<HTMLDivElement>) => {
  // Fires BEFORE child onClick handlers
  console.log("Captured click on:", e.target);
}}>
  <button onClick={() => console.log("Button clicked")}>
    Click me
  </button>
</div>

Event flow order: Capture (root to target) --> Target --> Bubble (target to root)

ALWAYS use capture-phase handlers when you need to intercept events before children process them (e.g., global escape key handling, focus trapping).

---

Form Events

onChange

Fires on every keystroke for text inputs (unlike native change which fires on blur):

const [value, setValue] = useState<string>("");

const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
  setValue(e.currentTarget.value);
};

<input type="text" value={value} onChange={handleChange} />

onSubmit

ALWAYS call e.preventDefault() to prevent page reload:

const handleSubmit = (e: React.FormEvent<HTMLFormElement>): void => {
  e.preventDefault();
  const formData = new FormData(e.currentTarget);
  submitForm(Object.fromEntries(formData));
};

<form onSubmit={handleSubmit}>
  <input name="email" type="email" required />
  <button type="submit">Submit</button>
</form>

---

Mouse Events

PropFires WhenBubbles
onClickClick (mousedown + mouseup)Yes
onDoubleClickDouble clickYes
onMouseDown / onMouseUpPress / releaseYes
onMouseEnterPointer enters elementNo
onMouseLeavePointer leaves elementNo
onMouseOver / onMouseOutPointer enters/leaves (includes children)Yes
onContextMenuRight-clickYes

onMouseEnter / onMouseLeave do NOT bubble -- they fire only for the exact element, not its children. Use these for hover states. Use onMouseOver / onMouseOut when you need bubbling behavior.

---

Keyboard Events

PropFires When
onKeyDownKey pressed down (repeats while held)
onKeyUpKey released

NEVER use onKeyPress -- it is deprecated and does not fire for non-character keys (Escape, Arrow keys, etc.).

Key Detection

ALWAYS use e.key (string value) instead of e.keyCode (deprecated numeric code):

const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {
  if (e.key === "Enter") {
    submitSearch();
  }
  if (e.key === "Escape") {
    clearInput();
  }
};

Modifier Keys

const handleShortcut = (e: React.KeyboardEvent<HTMLDivElement>): void => {
  if (e.key === "s" && (e.metaKey || e.ctrlKey)) {
    e.preventDefault(); // prevent browser save dialog
    saveDocument();
  }
};
PropertyKey
e.ctrlKeyCtrl (Windows/Linux)
e.metaKeyCmd (macOS) / Win (Windows)
e.shiftKeyShift
e.altKeyAlt / Option

---

Focus Events

PropFires WhenBubbles
onFocusElement gains focusYes (in React)
onBlurElement loses focusYes (in React)

React's onFocus and onBlur bubble, unlike the native focus/blur events. This matches the native focusin/focusout behavior.

relatedTarget

const handleBlur = (e: React.FocusEvent<HTMLInputElement>): void => {
  if (e.relatedTarget === null) {
    // Focus left the document entirely
    validateField();
  }
};

e.relatedTarget is the element that received (onBlur) or lost (onFocus) focus. It is null when focus moves outside the document.

---

React 18 vs React 19 Differences

FeatureReact 18React 19
Event delegationRoot containerRoot container (unchanged)
Event poolingRemoved (since 17)Removed
ref as propUse forwardRef for function componentsref is a regular prop -- no forwardRef needed
Form actionsNot available<form action={fn}> with useActionState

In React 19, forms can use the action prop directly. For new projects on React 19, prefer action + useActionState over manual onSubmit + preventDefault for form submissions with server mutations.

---

Reference Links

  • references/examples.md -- Complete event handling examples with TypeScript
  • references/api-table.md -- All synthetic event types with properties and TypeScript signatures
  • references/anti-patterns.md -- Common event handling mistakes and corrections

Official Sources

  • https://react.dev/learn/responding-to-events
  • https://react.dev/reference/react-dom/components/common#event-handler
  • https://react.dev/learn/typescript#typing-dom-events
  • https://react.dev/reference/react-dom/components/input
  • https://react.dev/reference/react-dom/components/form

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.