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.tsximport 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.tsximport Item from './Item'interface ItemType = {id: numbername: string}let count = 0const items = [{ id: 1, name: 'dracula' }{ id: 2, name: 'monte cristo' }] as ItemType[]function ItemList () {const increment = (id) => {count += 1console.log(`Id ${id} is incrementing.`)console.log('Current count is now:', count)}return (<div className="item-list">{items.map((item) => {return <Itemkey={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.tsximport React from 'react'interface Props {id: numbername: stringincrement: (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