1

I have a react bootstrap modal where I am mapping my data but the problem is when I click on modals, all the modals display same data, its apparently the last item of the array in all modals. I want to generate modal dynamically and show different data for different modal.

const content: { cardimg: string, Name: string, Post: string, Nation: string, About: string, mod:string }[] = [
{
"cardimg": `hello`,
"Name": "someone 1",
"Post": "Chairman & CEO",
"Nation": "India",
"About": "holds a degree of Executive MBA in Entrepreneurship from Rennes School of Business, France.",
"mod": "one"
},
{
"cardimg": `world`,
"Name": "someone 2",
"Post": "Deputy CEO",
"Nation": "India",
"About": "holds a degree in MBA Finance, someone 2 has more than 7 years of experience in Customer Engagement Services.",
"mod": "two"
},

const Leadershipcard = (prop: props) =\> {

    const [modalShow, setModalShow] = useState(false)
    
    
    return (
        <>
            {content.map((e) =>
                <div className="card col-lg-6 p-0" style={{ "width": "18rem" } as React.CSSProperties}>
                    <img src={`Assets\\About\\team\\${e.cardimg}.webp`} className="card-img-top" alt="..." />
                    <div className="card-body">
                        <h5 className="card-title">{e.Name}</h5>
                        <p className="card-text">{e.Post}</p>
                        <a href="/" className="d-block fs-4"><i className="fa-brands fa-linkedin-in"></i></a>
                        <button className="btn btn-outline-dark btn-dark rounded-0 text-bg-light mt-2 vi-more"
                            onClick={() => setModalShow(true)} data-bs-toggle="modal" data-bs-target={`/mod${e.mod}`}>View More</button>
                       ** <Modals
                            show={modalShow}
                            onHide={() => setModalShow(false)}
                            Img={e.cardimg}
                            Name={e.Name}
                            Post={e.Post}
                            Nation={e.Nation}
                            About={e.About}
                            mod={e.mod}
                        />**
                    </div>
                </div>
            )}
        </>
    )

}

export default Leadershipcard
[Modal component that I used (Bold text above)](https://i.stack.imgur.com/Cg01P.png)

1 Answers1

0

Modal states have to be maintained in an array to keep track of specific modals.

We can achieve it by passing index of array when opening and closing the modal.

import React, { useEffect, useState } from "react";
import { Button, Modal } from "react-bootstrap";

const Modals = ({ show, onHide, about, name }) => {
  return (
    <Modal show={show} onHide={onHide}>
      <Modal.Header closeButton>
        <Modal.Title>{name}</Modal.Title>
      </Modal.Header>
      <Modal.Body>{about}</Modal.Body>
      <Modal.Footer>
        <Button variant="secondary" onClick={onHide}>
          Close
        </Button>
      </Modal.Footer>
    </Modal>
  );
};

const content = [
  {
    cardimg: `hello`,
    Name: "someone 1",
    Post: "Chairman & CEO",
    Nation: "India",
    About:
      "Holds a degree of Executive MBA in Entrepreneurship from Rennes School of Business, France.",
    mod: "one"
  },
  {
    cardimg: `world`,
    Name: "someone 2",
    Post: "Deputy CEO",
    Nation: "India",
    About:
      "Holds a degree in MBA Finance, someone 2 has more than 7 years of experience in Customer Engagement Services.",
    mod: "two"
  }
];

const LeadershipCard = (prop) => {
  const [modalShow, setModalShow] = useState([]);

  const handShow = (index) => {
    const modalStateClone = [...modalShow];
    modalStateClone[index] = true;
    setModalShow(modalStateClone);
  };

  const handleClose = (index) => {
    const modalStateClone = [...modalShow];
    modalStateClone[index] = false;
    setModalShow(modalStateClone);
  };

  useEffect(() => {
    if (content?.length > 0) {
      const contentArr = content.map((c) => {
        return false;
      });
      console.log(contentArr);
      setModalShow(contentArr);
    }
  }, []);

  return (
    <>
      {content.map((e, index) => (
        <div
          className="card col-lg-6 p-0"
          style={{ width: "18rem" }}
          key={index}
        >
          <div className="card-body">
            <h5 className="card-title">{e.Name}</h5>
            <p className="card-text">{e.Post}</p>
            <a href="/" className="d-block fs-4">
              <i className="fa-brands fa-linkedin-in"></i>
            </a>
            <button
              className="btn btn-outline-dark btn-dark rounded-0 text-bg-light mt-2 vi-more"
              onClick={() => handShow(index)}
              data-bs-toggle="modal"
              data-bs-target={`/mod${e.mod}`}
            >
              View More
            </button>
            <Modals
              key={index}
              show={modalShow[index]}
              onHide={() => handleClose(index)}
              img={e.cardimg}
              name={e.Name}
              post={e.Post}
              nation={e.Nation}
              about={e.About}
              mod={e.mod}
            />
          </div>
        </div>
      ))}
    </>
  );
};

export default LeadershipCard;

I have created CodeSandbox here for live demo.

Sivadass N
  • 917
  • 4
  • 12
  • 23