Passing handlers down
Pass an onPlay handler from App through ShowCard into a Button.
In Handling clicks the function that ran on a click sat next to the button. The part of an app that knows what a click should mean is usually further up the tree.
The handler lives in App
App defines handlePlay and passes it down as a prop. ShowCard puts that
prop straight on its button.
Play on The Bear opens an alert reading Playing The Bear. Severance was given
no onPlay, so its button is handed undefined. Pressing it does nothing, and
React does not report the missing handler.
ShowCard does not know what Play means
The card only calls the function it was given. App picks the function, and
the title inside it.
Play on Severance alerts Playing Severance, and Watched on Severance prints
Watched Severance. Play on Andor alerts Playing The Bear.
ShowCard cannot catch that. It runs whatever App handed it, and App chose
the title.
A button that only forwards the click
Both buttons repeat the same styles. Move them into a Button component that
takes onClick and children.
children is the prop React fills with whatever sits between the opening and
closing tags. It is an ordinary prop, like the ones in Passing props to a
card.
Play works on all three cards. The function travels from App to ShowCard,
from ShowCard to Button, and on to the real <button>.
Watched does nothing on any card, and the console stays empty. The tag passes
onclick and Button reads onClick. On a component you wrote, a prop name
is just a name, so React has no list to check it against.
Name it onX
Two names for one click. In App the function is handlePlay, named for what
it does. On the tag the prop is onPlay, named for when it runs.
// In App: named for what happens.
function handlePlay(title) {
alert("Playing " + title);
}
// On the tag: named for when it runs.
<ShowCard title="The Bear" onPlay={() => handlePlay("The Bear")} />
onPlay and onWatched read like React's own onClick and onChange, so
anyone opening ShowCard knows they hold a function. Use the same name on the
tag and in the parameter list.
Common mistakes
- A prop name that does not match.
Apppassesplaywhile the card readsonPlay, so the button is handedundefinedand does nothing. - A wrapper that keeps the click.
Buttonhas to putonClickon its own<button>, or the function never gets there. - Calling the prop instead of passing it.
onClick={onPlay()}runs during the render, so writeonClick={onPlay}.
Exercise
Neither button does anything on any card, and the console has lines in it before you click.
Fix both, so nothing runs until a click. Then press Play on Severance and the
alert reads Playing Severance. Press Watched on Severance, then Watched on
Andor, and the console reads:
Watched Severance
Watched Andor
Hint: one prop name does not match the card, and one prop is being called instead of passed.