Event Handlers
What is an Event Handler?
Event Handlers are functions that can be triggered in response to a user interaction like clicking, hovering, focussing, or more.
Event handler functions are usually defined inside of your components and have names that start with handle, and then are followed by the name of the event.
Adding an Event Handler
How to add an Event Handler
Step 1: defining a function.
Step 2: pass it as a prop to whatever JSX flag is appropriate.
export default function Button() {
return (
<button>I don't do anything</button>
)
}
Now, you want it to show a message that appears once the user clicks on it. There are a few simple steps you can take to achieve this goal:
Step 1: Declare a function called
handleClick
inside of theButton
component.Step 2: Implement the logic inside that function.
Step 3: Add an
onClick={handleClick}
to the<button>
JSX.
export default function Button() {
function handleClick() {
alert('You clicked me!')
}
return (
<button onClick={handleClick}>Click me</button>
)
}
Reading Props in Event Handlers
Event handlers are declared inside of a component and can therefore access the components props. This means that if the component has a message
prop, you can make the button event show that message once clicked using the handleClick
.
Passing Event Handlers as Props
You can have the parent component specify a child's event handler.
This can be achieved by passing a prop that the component receives from its parent as the event handler.
In the example, this is a component named Toolbar
, which renders PlayButton
and UploadButton
.
One:
PlayButton
passeshandlePlayClick
as theonClick
prop to theButton
inside.Two:
UploadButton
passes() => alert('Uploading!)
as theonClick
prop to theButton
inside.
And then, your Button
also accepts the prop called onClick
. This passes the prop directly to the <button>
with the onClick={onClick}
.
function Button({ onClick, children }) {
return (
<button onClick={onClick}>
{children}
</button>
)
}
function PlayButton({ movieName }) {
function handlePlayClick() {
alert(`Playing ${movieName}!`)
}
return (
<Button onClick={handlePlayClick}>
Play "{movieName}"
</Button>
)
}
export default function Toolbar() {
return (
<div>
<PlayButton movieName="Delivery Service" />
<UploadButton />
</div>
)
}
Naming Event Handler Props
<button>
and <div>
are built in components, and they only support browser event names like onClick
.
But, when you build your own components, you can name their event handler props any way you like to.
So, when inside of a component, the example of the button we used previously, does not have to be called onClick
but we could also have named that onSmash
.
The <button>
in lowercase still needs the onClick
prop, but everywhere else, you could use onSmash
.
Event Propagation
The cool thing about event handlers is that it will also catch events from any children your component might have. You can call this "bubbling" or "propagating" up the tree. Basically, this means that it starts where the event happened, and then goes up the tree.
Stopping Propagation
Quick Tip: the only argument an event handler receives is an event object. This is usually called e
which stands for "event". This object can be used to read information about the event.
The event object mentioned above can also make you stop the propagation. You can do this when you want to prevent an event from reaching parent components. You can call e.stopPropagation()
.
Passing Handlers as alternatives to propagation
Example code:
function Button({ onClick, children }) {
return (
<button onCLick={e => {
e.stopPropagation()
onClick()
}}>
{children}
</button>
)
}
As you can see, the click handler only runs the onClick
prop that is passed by the parent after the click handler runs a line of code.
You can add more code to this handler before calling the parent onClick
. This is an alternative to propagation, since it lets the child component handle the event whilst the parent component can still specify additional behavior.
Preventing Default Behavior
Browsers can have default behavior associated with them. You can call e.preventDefault()
on the event object to stop this from happening.
export default function Signup() {
return (
<form onSubmit={e => {e.preventDefault();alert('Submitting!');}}>
<input />
<button>Send</button>
</form>
)
}
A few notes
Functions that are passed to event handlers must actually be passed and not called.
// this is correct
<button onClick={handleClick}> </button>
// this is incorrect
<button onClick={handleClick()}> </button>