Handling clicks

Attach a click handler to a show card, and pass the function instead of calling it.

The watchlist draws its cards, but there is nothing on them to press yet. A click handler is an ordinary function that you hand to React.

A button on a card

Each card gets a small Play button. You give its onClick prop a function, and React calls that function when the button is clicked.

import "./styles.css";
import ShowCard from "./ShowCard";

export default function App() {
  return (
    <div className="page">
      <ShowCard title="The Bear" year={2022} genre="Drama" rating={8.6} still="still-warm" />
    </div>
  );
}

Press Play and the console prints Playing The Bear. Nothing is printed before that, because React holds the function and only calls it on a click.

The prop is onClick, with a capital C. React event props are camelCase, so onclick is not one of them.

Pass the function, do not call it

handlePlay and handlePlay() look almost the same. The first one is the function itself. The second one runs the function straight away and gives you back whatever it returned.

The card below has both. Read the console before you click anything.

import "./styles.css";
import ShowCard from "./ShowCard";

export default function App() {
  return (
    <div className="page">
      <ShowCard title="The Bear" year={2022} genre="Drama" rating={8.6} still="still-warm" />
    </div>
  );
}

The console already reads Playing The Bear before any click. That is the broken button firing while React draws the card. In development React draws each component twice, so the line appears twice.

handlePlay() returns nothing, so React is handed undefined as the handler. Clicking Play (broken) does nothing at all.

Passing a title

Three cards can share one function, but then that function has to be told which show to play. So playShow takes a title.

onClick still needs a function, so you cannot write playShow(title) there. Wrap the call in an arrow instead: () => playShow(title). Arrows are Arrow Functions and this.

import "./styles.css";
import ShowCard from "./ShowCard";

export default function App() {
  return (
    <div className="page">
      <ShowCard title="The Bear" year={2022} genre="Drama" rating={8.6} still="still-warm" />
      <ShowCard title="Severance" year={2022} genre="Thriller" rating={8.7} still="still-cold" />
      <ShowCard title="Andor" year={2022} genre="Sci-Fi" rating={8.4} still="still-dusty" />
    </div>
  );
}

Play on Severance prints Playing Severance, and Play on Andor prints Playing Andor. Each card builds its own little arrow function, and that arrow knows its own title.

Watched has no arrow. React calls a handler with the click event, so title is that event, and the console reads Watched [object Object].

Common mistakes

  • onClick={handlePlay()}. The parentheses run the function during the render and hand React its return value, so drop them.
  • onclick. React event props are camelCase, so onClick is the spelling React reads.
  • onClick="handlePlay". A handler is a function, not a piece of text, so pass it in braces.

Exercise

Both buttons in ShowCard are wired wrongly. The console has lines in it before you click anything, and Play does nothing when you do click it.

Fix both, so nothing is printed until a click. Then press Play and Watched on the Severance card, and the console reads:

Playing Severance
Watched Severance

Hint: drop the parentheses, and wrap each call in an arrow so it is given its own title.

import "./styles.css";
import ShowCard from "./ShowCard";

export default function App() {
  return (
    <div className="page">
      <ShowCard title="The Bear" year={2022} genre="Drama" rating={8.6} still="still-warm" />
      <ShowCard title="Severance" year={2022} genre="Thriller" rating={8.7} still="still-cold" />
      <ShowCard title="Andor" year={2022} genre="Sci-Fi" rating={8.4} still="still-dusty" />
    </div>
  );
}