skip to Main Content

I’m new to React, but I’m trying to create the functionality where a user can click on any one of the listed profile cards and then display a modal highlighting information about the respective card that the user clicked.

Currently, I’ve built out the code for the modal and for the list of profile cards to be outputted through {FounderList}. Each of these profile cards contains a button which toggles the modal, but I’d also like for this button to pass information to the children of <Modal/> in Home.jsx (see where {ModalContent} currently sits in the file) about the respective profile the user clicked on.

As you can see in the photos, my modal currently contains no information if I were to click on "Mark Davis" for example, although I’m attempting to pass the index for this user into the <Modal/> children. My understanding is that this doesn’t work because the content is immediately rendering while ModalContent remains undefined, but I’m not sure how to solve any of this. Is this where another useState would come into use? How might I go about implementing that?

Home.jsx

import React, { useState } from "react";

function Home() {
  // Modal Toggle
  const [isOpen, setIsOpen] = useState(false);

  // List of Founders
  const FounderPhotoList = [Founder1, Founder2, Founder3, Founder4];
  const FounderNameList = [
    "Mark Davis",
    "Emil Robinson",
    "David Kim",
    "Alice Nguyen",
  ];

  var ModalContent;

  let FounderList = FounderPhotoList.map((photo, index) => {
    return (
      <React.Fragment key={index}>
        <ContentCard>
          <img
            src={photo}
            className="object-cover object-center h-4/5 rounded-sm drop-shadow-lg"
          ></img>
          <button
            className="bg-green-100 hover:bg-green-300 font-bold drop-shadow-lg"
            onClick={() => {
              ModalContent = <p>{index}</p>;
              setIsOpen(true);
            }}
          >
            {FounderNameList[index]}
          </button>
        </ContentCard>
      </React.Fragment>
    );
  });

console.log(ModalContent);

  return (
    <>
        <PageCarousel>
          <Modal open={isOpen} onClose={() => setIsOpen(false)}>
            <ContentCard>
              {ModalContent}
            </ContentCard>
          </Modal>
          <TitleText>Meet the Founders</TitleText>
          <div className="grid grid-cols-2 grid-rows-2 gap-6 h-5/6 mt-4 w-5/6 mx-auto">
            {FounderList}
          </div>
        </PageCarousel>
    </>
  );
}

export default Home;

Modal.jsx

function Modal({ open, children, onClose }) {
  if (!open) return null;

  return (
    <>
        <div className="bg-black bg-opacity-40 fixed h-full w-full top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-50">
          <div className="fixed h-4/5 w-4/5 top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
            <p className="text-white">{children}</p>
            <button className="text-black font-bold bg-green-200 mt-2 text-xl align-text-top" onClick={onClose}>
            &nbsp; Exit &nbsp;
            </button>
          </div>
        </div>
    </>
  );
}

export default Modal;

enter image description here
enter image description here

2

Answers


  1. You need to save the clicked profile to a useState (rendering the component once set), and then you can use that inside of your modal content:

    import React, { useState } from "react";
    
    function Home() {
      // Modal Toggle
      const [isOpen, setIsOpen] = useState(false);
      const [profile, setProfile] = useState(undefined);    
    
      // List of Founders
      const FounderPhotoList = [Founder1, Founder2, Founder3, Founder4];
      const FounderNameList = [
        "Mark Davis",
        "Emil Robinson",
        "David Kim",
        "Alice Nguyen",
      ];
    
      var ModalContent;
    
      let FounderList = FounderPhotoList.map((photo, index) => {
        return (
          <React.Fragment key={index}>
            <ContentCard>
              <img
                src={photo}
                className="object-cover object-center h-4/5 rounded-sm drop-shadow-lg"
              ></img>
              <button
                className="bg-green-100 hover:bg-green-300 font-bold drop-shadow-lg"
                onClick={() => {
                  setProfile([The data about the profile])
                  setIsOpen(true);
                }}
              >
                {FounderNameList[index]}
              </button>
            </ContentCard>
          </React.Fragment>
        );
      });
    
    console.log(ModalContent);
    
      return (
        <>
            <PageCarousel>
              <Modal open={isOpen} onClose={() => setIsOpen(false)}>
                <ContentCard>
                  profile !== undefined && (
                  <p>{profile.name}</p>
                 )
                </ContentCard>
              </Modal>
              <TitleText>Meet the Founders</TitleText>
              <div className="grid grid-cols-2 grid-rows-2 gap-6 h-5/6 mt-4 w-5/6 mx-auto">
                {FounderList}
              </div>
            </PageCarousel>
        </>
      );
    }
    
    export default Home;
    

    Although I will say the way this is structured makes it very difficult to do, but essentially you need to set state of the profile data when the profile is clicked, that way we can use that in the modal display. You need to create something (You don’t need too, however, much less chance of bugs if you forget to add one value to both of the arrays vs the data being held together in an object) that can be the founder photo + the data (such as name) maybe something like

     Founders = [{ photo: Founder1, name: "Mark Davis"}];
    

    The it becomes extremely simple to

    setProfile(founder); 
    

    as you map through the array

    Something like this

    FounderPhotoList.map((founder, index) => {
        return (
          <React.Fragment key={index}>
            <ContentCard>
              <img
                src={founder.photo}
                className="object-cover object-center h-4/5 rounded-sm drop-shadow-lg"
              ></img>
              <button
                className="bg-green-100 hover:bg-green-300 font-bold drop-shadow-lg"
                onClick={() => {
                setProfile(founder);
                  setIsOpen(true);
                }}
              >
                {founder.name}
              </button>
            </ContentCard>
          </React.Fragment>
        );
      });
    
    Login or Signup to reply.
  2. To pass information about the respective profile that the user clicked on to the Modal component, you can utilize React’s state management. You can create a state variable to hold the information about the selected profile and update it when a user clicks on a profile card. Here’s how you can do it:

    First, define a state variable to hold the selected profile information in your Home component:

    const [selectedProfile, setSelectedProfile] = useState(null);
    

    Modify the click event handler for each profile card button to update the selectedProfile state with the relevant information when a user clicks on a card:

    <button
      className="bg-green-100 hover:bg-green-300 font-bold drop-shadow-lg"
      onClick={() => {
        setSelectedProfile({
          name: FounderNameList[index], // Store the name
          photo: FounderPhotoList[index], // Store the photo or any other relevant data
        });
        setIsOpen(true); // Open the modal
      }}
    >
      {FounderNameList[index]}
    </button>
    

    In your Modal component, you can now use the selectedProfile state to display the information:

        <Modal open={isOpen} onClose={() => setIsOpen(false)}>
      <ContentCard>
        {selectedProfile && (
          <>
            <img
              src={selectedProfile.photo}
              alt={selectedProfile.name}
              className="object-cover object-center h-4/5 rounded-sm drop-shadow-lg"
            />
            <p>{selectedProfile.name}</p>
          </>
        )}
        <button
          className="text-black font-bold bg-green-200 mt-2 text-xl align-text-top"
          onClick={() => {
            setIsOpen(false);
            setSelectedProfile(null); // Clear the selected profile when closing the modal
          }}
        >
          &nbsp; Exit &nbsp;
        </button>
      </ContentCard>
    </Modal>
    

    By using the selectedProfile state, you can store the information about the profile that the user clicked on and display it within the Modal component. When the modal is closed, you can clear the selectedProfile state to ensure that it doesn’t persist when the modal is reopened or closed.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search