Back to Interview PrepGet interview ready with AILearn each topic the way interviewers ask it, then answer like you would in the interview.
Course progress0/14 chapters · 0%

Chapter 4 of 15

~11 min

Event Handling

React wraps the browser's native events in its own synthetic event system, but the day-to-day experience of handling clicks, input changes, and form submissions feels very close to plain JavaScript once you know the conventions.

Attaching Event Handlers

Event handlers are passed as props named for the event, in camelCase: `onClick`, `onChange`, `onSubmit`. You pass a function reference, not a function call - `onClick={handleClick}`, never `onClick={handleClick()}`, since the latter would call it immediately during render instead of on click.

Try it yourself

function ClickCounter() {
  const [clicks, setClicks] = useState(0);

  function handleClick() {
    setClicks(clicks + 1);
  }

  return <button onClick={handleClick}>Clicked {clicks} times</button>;
}

render(<ClickCounter />);
Output

Inline Arrow Functions and Passing Arguments

When a handler needs an argument, wrap it in an inline arrow function so it is not called immediately: `onClick={() => handleSelect(id)}`. This is extremely common for list items where each one needs to know which item was clicked.

Try it yourself

function FruitList() {
  const [selected, setSelected] = useState('');
  const fruits = ['Apple', 'Banana', 'Cherry'];

  return (
    <div>
      {fruits.map(fruit => (
        <button key={fruit} onClick={() => setSelected(fruit)} style={{ marginRight: 6 }}>
          {fruit}
        </button>
      ))}
      <p>Selected: {selected || 'none'}</p>
    </div>
  );
}

render(<FruitList />);
Output

Selected: none

The Synthetic Event Object

React handlers receive a SyntheticEvent - a cross-browser wrapper around the native event with the same familiar API (`event.target`, `event.preventDefault()`, `event.stopPropagation()`). It exists so your event-handling code behaves consistently across browsers without you needing to special-case anything.

Preventing Default Behavior

Forms are the classic case: submitting a `<form>` normally reloads the page, so a form's `onSubmit` handler almost always starts with `event.preventDefault()` to stop that and handle the submission in JavaScript instead.

Try it yourself

function SearchForm() {
  const [query, setQuery] = useState('');
  const [lastSearch, setLastSearch] = useState('');

  function handleSubmit(event) {
    event.preventDefault();
    setLastSearch(query);
  }

  return (
    <form onSubmit={handleSubmit}>
      <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search..." />
      <button type="submit">Go</button>
      <p>Last search: {lastSearch || 'none yet'}</p>
    </form>
  );
}

render(<SearchForm />);
Output

Last search: none yet

Handling Common Input Events

`onChange` fires on every keystroke for text inputs (unlike the DOM's native `change`, which only fires on blur) - this is what makes controlled inputs practical. `onKeyDown`/`onKeyUp` give you access to which key was pressed, useful for things like submitting on Enter.

Coding challenge

Build a component with a text input and a button. Clicking the button should log the current input value into a list of "submitted" messages shown below, and clear the input afterward.

function MessageBox() {
  // write your code here
  return null;
}

render(<MessageBox />);
Output

Answer every question below to mark this chapter as complete.

Quiz Yourself

Score: 0/4

1. How should you attach a click handler that needs an argument, like `handleSelect(id)`?

2. What is a SyntheticEvent in React?

3. Why do form `onSubmit` handlers typically call `event.preventDefault()`?

4. How does React's onChange for text inputs differ from the native DOM change event?

You're viewing a free lesson. Sign up free to track your progress and unlock the full course.Sign up freeSign in