Event Delegation

In order to respond to user events, the onEvent attributes in the elements should be given the value of a local function.

// MyComponent.tsx
import React from 'react';
function MyComponent() {
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
const { name } = event.target;
console.log(`The button named ${name} was clicked`);
};
return (
<div>
<button name="green" onClick={handleClick}>Green</button>
<button name="yellow" onClick={handleClick}>Yellow</button>
<button name="red" onClick={handleClick}>Red</button>
</div>
);
}
export default MyComponent;

Sometimes the event handler needs to be located in a parent component, but is fired in a child component. In this case, a function is passed into a child component. In the following example, an increment function in the <ItemList /> component is passed as a prop to the <Item /> component.

// ItemList.tsx
import Item from './Item'
interface ItemType = {
id: number
name: string
}
let count = 0
const items = [
{ id: 1, name: 'dracula' }
{ id: 2, name: 'monte cristo' }
] as ItemType[]
function ItemList () {
const increment = (id) => {
count += 1
console.log(`Id ${id} is incrementing.`)
console.log('Current count is now:', count)
}
return (
<div className="item-list">
{items.map((item) => {
return <Item
key={item.id}
id={item.id}
name={item.name}
increment={increment}
/>
})}
</div>
)
}
export default ItemList

Notice how the local increment function is being passed as a prop to the <Item /> component. Here, we're just passing a function to another function. Additionally, notice how an id argument is passed to the increment function. This is how the parent component knows which item incremented the count.

This next code snippet shows how the increment function is used inside the handleClick event handler.

// Item.tsx
import React from 'react'
interface Props {
id: number
name: string
increment: (id: number) => void
}
function Item (props: Props) {
const handleClick = () => {
props.increment(props.id)
}
return (
<div className="item">
<h2>{props.name}</h2>
<button onClick={handleClick}>Increment</button>
</div>
)
}
export default Item