Children components sometimes need to change values inside a parent component’s state. This is why we have an “Increase parent count” button in the child component.
What we can do is emit a custom event from the child component to the parent component. The parent then listens to this event and responds accordingly.
Creating a custom event
We can create a custom event with new CustomEvent. It has the following syntax:
const event = new CustomEvent(eventName, eventOptions)
eventName is the name of the event we want to create.
eventOptions is the options we’re passing into the event.
Let’s create a custom event called hello-world for example. Here’s how it will look like:
const event = new CustomEvent('hello-world')
console.log(event)
Custom events do not bubble by default. We can allow bubbling by passing bubbles: true to the event options.
const event = new CustomEvent('hello-world', {
bubbles: true
})
console.log(event)
Emitting an event
Any DOM element can emit an event. To emit the event, we call the dispatchEvent method.
element.dispatchEvent(event)
Here’s an example. Say we have the following HTML. When we click on the button, we want to emit a hello-world event.
When someone clicks on the “increase parent count” button, we want to dispatch an event from the child component to the parent component. Dispatching an event is also called emitting an event.
To emit this event, we’ll create a method called emit. We’ll add this method to options so users can use it.
export default function Tiny (options) {
// ...
options.emit = function () {
// ...
}
// ...
}
In emit, we need to create and dispatch a custom event. To create the event, we need the event name and options. For options, the only thing we’re interested in is the detail property, so we’ll ask users to pass in detail instead.
export default function Tiny (options) {
// ...
options.emit = function (eventName, detail) {
// ...
}
// ...
}
We’ll then create and dispatch the event from the child component.
export default function Tiny (options) {
// ...
options.emit = function (eventName, detail) {
const event = new CustomEvent(eventName, {
bubbles: true,
detail
})
options.element.dispatchEvent(event)
}
// ...
}
To make the code slightly more robust, we may want to include a third (but optional) eventOpts argument. This lets users customize the event they want to emit.
In increaseSelfCount, we can get amount (which was passed from the child component into the event) via the detail property. Once we have this, we can call setState to update the state and the UI.