Search code examples
reactjsuse-effectreact-propsuse-state

How to update State Hook with onClick listener on React Component Instance


I'm attempting to add an onClick to a component instance which changes the state of a useState hook, and prints it out to the console. However, nothing fires when the component instance is clicked.

I have tried wrapping it in a JSX div element and adding an onClick to the div which works in printing to the console, but the state is not updated as always shows an undefined.

The end goal is to pass the state to another component (Linked page) after click.

Here is my code.

Card.js

export default function Card(props) {
  return (
    <div className="card" style={{ background: `${props.background}` }}>
      <h2>{props.taskName}</h2>
      <p>{props.description}</p>
    </div>
  );
}

Home.js

import { Link } from "react-router-dom";
import { useState, useEffect } from "react";
import Card from "../components/Card";
import "../pages/Home.scss";
import ProfileButton from "../components/ProfileButton";
import Header from "../components/Header";
import "./PlayerPage";

export default function Home() {
  const date = new Date();
  const time = date.getHours();
  let timeOfDay;

  if (time < 12) {
    timeOfDay = "Morning";
  } else if (time >= 12 && time < 6) {
    timeOfDay = "Afternoon";
  } else {
    timeOfDay = "Evening";
  }

  const [task, setTask] = useState();

  useEffect(() => {
    console.log(task);
  })

 return (
  <>
   <Header />
    <main className="home-main">
     <div className="main-wrap">
      <section className="card-container">
       <h1>Good {timeOfDay}</h1>
        <h1>Choose Your Work Style</h1>

         <div className="card-wrap">
          <Link to="/PlayerPage">
           <Card onClick={() => {console.log("hey") }}
            taskName="Short Task"
            description="Lorem ipsum dolor sit amet, consectetur adipiscing elit."
         />
          </Link>
     </div>
</>
);
}

PlayerPage.js - (Component which needs to display updated state)

export default function PlayerPage() {
  return (
    <>
      <Header />
      <main className="player-page-main">
        <div className="player-page-main-wrap">
          <div className="timer-title-wrap">
            <Timer />
            <h2 className="task-title">{Updated state here}</h2>
          </div>
        </div>
      </main>
    </>
  );
}

Solution

  • The Card component needs to attach the passed onClick handler prop to a DOM element.

    Example:

    export default function Card(props) {
      return (
        <div
          className="card"
          style={{ background: `${props.background}` }}
          onClick={props.onClick}
        >
          <h2>{props.taskName}</h2>
          <p>{props.description}</p>
        </div>
      );
    }