Events and forms

Pass data to an event handler

Wrap a call in a small arrow function when the handler needs an item id or another render-time value.

Sometimes a click handler needs data from the current render, like a task ID. You cannot pass that data as a direct function call. React would run it while rendering, not when the user clicks.

Wrap the call in an arrow function instead:

function Task({ task, onRemove }) {
  return (
    <button onClick={() => onRemove(task.id)}>
      Remove {task.title}
    </button>
  )
}

The arrow function is the event handler. React calls it later, when the user clicks. It then calls onRemove with the task ID captured by this render.

This is a common mistake:

<button onClick={onRemove(task.id)}>Remove</button>

That calls onRemove while rendering. You will see the remove logic fire on every render, not on click. The page may look broken before you touch anything.

Pass a stable identifier rather than the list index. If items move, an index can point to a different task by the time the parent updates its state. IDs from your data model stay correct through reordering.

You can pass the browser event too when needed:

onClick={event => onRemove(task.id, event)}

Most application handlers need the domain value more than the raw event. Keep the child callback focused on the intent. The parent decides what to do with the ID.

The same pattern works for any render-time value: a selected tab index, a filter name, or a row from a map() loop. The rule is always the same. Pass a function that React calls later, not the result of calling your handler now.

Try this on your own project: reorder a task list, remove one item, and confirm the correct ID reaches the parent. Log task.id in the parent handler if you want proof.

Lesson completed