Handlers as Props
In a real app, buttons are in components of their own: the Vote button is in BandCard. But what a vote does belongs to App, which has the whole lineup, and soon the number of votes. So App writes the handler and gives it to each card as a prop. In App.jsx:
function handleVote(name) {
console.log(`Your vote: ${name}`);
}
return (
<ul>
{bands.map((band) => (
<BandCard key={band.id} band={band} onVote={handleVote} />
))}
</ul>
);A function is a value like any other, so it can be a prop, just like a text or a number. BandCard reads it from its props and calls it when its button is clicked. In BandCard.jsx:
export default function BandCard({ band, onVote }) {
return (
<li className="card">
<h2>{band.name}</h2>
<button onClick={() => onVote(band.name)}>Vote</button>
</li>
);
}On a click, the button runs the arrow function, which calls onVote("Owl Choir"), and onVote is handleVote from App. So a click in the card runs code in App. The card doesn't need to know what a vote does. It only reports that someone voted for its band.
The prop is called onVote, like onClick on a button: on and what happened. The function that App passes is handleVote. These are conventions again: props for handlers are called onSomething, and handler functions handleSomething. But onVote is an ordinary prop. React doesn't call it by itself, as it calls onClick on a button; it's BandCard that calls it.
A typical mistake: onClick={onVote} in the card. Then React calls onVote with the event object instead of the name, and App prints Your vote: [object Object].
Instructions
In App, write handleVote(name) that prints Your vote: Owl Choir, with the name it gets, and pass it to every BandCard as the prop onVote. In BandCard.jsx, read onVote from the props, and call it with the band's name when Vote is clicked.
Do the same for the button Details, with the prop onDetails. The card calls it with the whole band, and handleDetails(band) in App prints Owl Choir: Forest Stage, 16:00.