REACT Contents

Typing Event Handlers

Type DOM events at boundaries, then extract primitives immediately. Prevent handler bugs from mixed element types, stale closures, and event object leakage across async boundaries.

On this page

Boundary Rule

  • Type the event at the UI boundary, then convert it to domain primitives.
  • Do not pass event objects to business logic or async code.
  • Prefer onChange signatures like (value) instead of (event).

Common Event Types

  • React.ChangeEvent for inputs and selects.
  • React.MouseEvent for clicks.
  • React.FormEvent for form submit.

Example: Extract Primitive Value

function SearchBox({ value, onValue }) {
  function onChange(e: React.ChangeEvent<HTMLInputElement>) {
    onValue(e.target.value);
  }

  return <input value={value} onChange={onChange} />;
}

Example: Submit Handler

function Form({ onSave }) {
  async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    await onSave();
  }

  return (
    <form onSubmit={onSubmit}>
      <button>Save</button>
    </form>
  );
}

Mixed Element Pitfall

  • A generic handler typed for one element can break when reused for another element.
  • Use separate handlers or type a union only when logic is truly shared.

Failure Modes

  • Passing event objects into async functions and using them later.
  • Incorrect event type causing unsafe casts.
  • Stale closures reading old state inside handlers.
  • Handlers doing heavy work on the main thread.

Production Checklist

  • Handlers translate DOM events into domain intent quickly.
  • Only primitives cross component boundaries.
  • Submit handlers have in flight guards.
  • High frequency handlers are debounced or throttled.