skip to Main Content

I have two components and I’m struggling to create e function in the first component (by clicking a certain button) and the effect to be in the second component (changing the text on the screen). (I’m new to React and I’m not quite sure how to approach this)

All I want is to create a function on the 3 buttons (daily, weekly and monthly) in the Main component and change the text in the Content component into the <div> with the "progress" className for <h1> respective <h5>

This is the first component:

export default function Main() {
  return (
    <main>
      <div className="second-card">
        <div className="main-card">
          <img
            className="avatar-logo"
            src="/images/image-jeremy.png"
            alt="Avatar"
          />
          <div className="main-card-details">
            <p>Report for</p>
            <h1>Jeremy Robson</h1>
          </div>
        </div>

        <div className="stats">
          <button className="daily">Daily</button>
          <button className="weekly">Weekly</button>
          <button className="monthly">Monthly</button>
        </div>
      </div>
    </main>
  );
}

This is the second one:

export default function Content(props) {
  return (
    <div className="dashboard-card">
      <div className="icons">
        <img className="card-icon" src={props.img} alt="activity icon" />
      </div>

      <div className="card-details">
        <div className="card-activity-title">
          <p>{props.activity}</p>
          <img
            className="ellipsis-icon"
            src={props.cardIcon}
            alt="Ellipsis card icon"
          />
        </div>

        <div className="progress">
          <h1>{props.WeeklyHours}</h1>
          <h5>{props.Weeklydate}</h5>
        </div>
      </div>
    </div>
  );
}

This is what I tried, but is basically creating a new card and not modifying the existing ones

// import React, { useState } from "react";
// import Content from "./Content";

export default function Main() {
  // const [contentData, setContentData] = useState({
  //   DailyHours: "0 hours",
  //   DailyDate: "Default Date",
  // });

  // function changeMessage1() {
  //   setContentData({
  //     DailyHours: "10 hours",
  //     DailyDate: "Date 1",
  //   });
  // }

  // function changeMessage2() {
  //   setContentData({
  //     DailyHours: "20 hours",
  //     DailyDate: "Date 2",
  //   });
  // }

  // function changeMessage3() {
  //   setContentData({
  //     DailyHours: "30 hours",
  //     DailyDate: "Date 3",
  //   });
  // }

  return (
    <main>
      <div className="second-card">
        <div className="main-card">
          <img
            className="avatar-logo"
            src="/images/image-jeremy.png"
            alt="Avatar"
          />
          <div className="main-card-details">
            <p>Report for</p>
            <h1>Jeremy Robson</h1>
          </div>
        </div>

        <div className="stats">
          <button className="daily">Daily</button>
          <button className="weekly">Weekly</button>
          <button className="monthly">Monthly</button>
        </div>
      </div>

      {/* <Content
        WeeklyHours={contentData.DailyHours}
        Weeklydate={contentData.DailyDate}
      /> */}
    </main>
  );
}

2

Answers


  1. React allows components to communicate with one another by lifting the state up to a common ancestor, the Main component in our example, and passing down the required state and functions to the child components as props. To add this capability, you can change your code as follows:

    import React, { useState } from "react";
    import Content from "./Content";
    
    export default function Main() {
      const [selectedInterval, setSelectedInterval] = useState("daily");
    
      const handleIntervalChange = (interval) => {
        setSelectedInterval(interval);
      };
    
      let contentData = {
        DailyHours: "0 hours",
        DailyDate: "Default Date",
      };
    
      // Modify contentData based on the selected interval
      switch (selectedInterval) {
        case "daily":
          contentData = {
            DailyHours: "10 hours",
            DailyDate: "Date 1",
          };
          break;
        case "weekly":
          contentData = {
            DailyHours: "20 hours",
            DailyDate: "Date 2",
          };
          break;
        case "monthly":
          contentData = {
            DailyHours: "30 hours",
            DailyDate: "Date 3",
          };
          break;
        default:
          break;
      }
    
      return (
        <main>
          <div className="second-card">
            <div className="main-card">
              <img
                className="avatar-logo"
                src="/images/image-jeremy.png"
                alt="Avatar"
              />
              <div className="main-card-details">
                <p>Report for</p>
                <h1>Jeremy Robson</h1>
              </div>
            </div>
    
            <div className="stats">
              <button className="daily" onClick={() => handleIntervalChange("daily")}>
            Daily
          </button>
          <button className="weekly" onClick={() => handleIntervalChange("weekly")}>
            Weekly
          </button>
          <button className="monthly" onClick={() => handleIntervalChange("monthly")}>
            Monthly
          </button>
        </div>
      </div>
    
      <Content
        WeeklyHours={contentData.DailyHours}
        Weeklydate={contentData.DailyDate}
      />
    </main>
      );
    }
    

    With this change, the status of the chosen interval (daily, weekly, or monthly) is stored in the Main component, which changes it in response to button presses. This changed state is sent to the Content component as props, which then shows the appropriate data.

    Ensure that the rendering logic in the Content component is adjusted to display the Weeklydate and Weekly Hours props that were received in the desired way.

    Login or Signup to reply.
  2. You can create a data object outside the component with all intervals and values and use it like this.

    import React, { useState } from "react";
    import Content from "./Content";
    
    const intervals = ["daily", "weekly", "monthly"];
    const data = {
      daily: {
        DailyHours: "10 hours",
        DailyDate: "Date 1",
      },
      weekly: {
        DailyHours: "20 hours",
        DailyDate: "Date 2",
      },
      monthly: {
        DailyHours: "30 hours",
        DailyDate: "Date 3",
      },
      default: {
        DailyHours: "0 hours",
        DailyDate: "Default Date",
      },
    };
    
    export default function Main() {
      const [selectedInterval, setSelectedInterval] = useState("default");
      const interval = data[selectedInterval];
    
    
      return (
        <main>
          <div className="second-card">
            <div className="main-card">
              <img
                className="avatar-logo"
                src="/images/image-jeremy.png"
                alt="Avatar"
              />
              <div className="main-card-details">
                <p>Report for</p>
                <h1>Jeremy Robson</h1>
              </div>
            </div>
    
            <div className="stats">
              {
                intervals.map((interval) => (
                  <button
                    key={interval}
                    className={interval}
                    onClick={() => setSelectedInterval(interval)}
                  >
                    {interval}
                  </button>
                ))
              }
            </div>
          </div>
    
          <Content
            WeeklyHours={interval.DailyHours}
            Weeklydate={interval.DailyDate}
          />
        </main>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search