最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - how to use modal inside a map function? - Stack Overflow

programmeradmin1浏览0评论

I am trying to a make Gallery application using React.JS and Reactstrap. I'm using the map() function to display every piece of art in a Card. In every card, there is a button that opens a modal to show more data from the map function. My problem is when I'm clicking the button to open modal from any card it shows the data from the last card on the page.

The code:

const Artcards = ({ state, loading }, props) => {
  const { buttonLabel, className } = props;

  const [modal, setModal] = useState(false);

  const toggle = () => setModal(!modal);



  if (loading) {
    return <h2>Loading</h2>;
  }

  return (
    <CardGroup className="CardGroup">
      {state.map((state, index) => {
        return (
          <div key={index}>
            <Card className="Card" style={{ padding: "0", height: "39rem" }}>
              <CardBody className="pt-3">
                <CardTitle className="CardTitle">
                  Art Name:
                  <h6 className="CardParagraph">{state.artName}</h6>
                </CardTitle>
                <CardSubtitle>
                  Artist Name:
                  <h6 className="CardParagraph">{state.artistName}</h6>
                </CardSubtitle>
                <CardImg
                  top
                  src={state.source}
                  alt={state.artName}
                />
              </CardBody>
              <CardBody>
                <CardText>
                  Description:
                  <div className="CardParagraph">{state.description}</div>
                </CardText>
                <CardText>
                  Price:<div className="CardParagraph">{state.price} </div>
                </CardText>
                <Button size="sm" color="danger" className=" m-1">
                  Buy
                </Button>
                <br></br>
                <Button color="success" onClick={toggle}>
                  Contact Artist
                </Button>
              </CardBody>
              <Modal
                isOpen={modal}
                state={state}
                fade={false}
                toggle={toggle}
                className={className}
              >
                <ModalHeader className="bg-dark text-primary" toggle={toggle}>
                  here the {state.artistName} should be
                </ModalHeader>
                <ModalBody>
                  <p>Header:{state.artName}</p>
                  <textarea
                    style={{ overflow: "auto", resize: "none"}}
                    rows="5"
                    cols="60"
                    placeholder="Write your message"
                  ></textarea>
                  <Input
                    type="text"
                    placeholder="Write Email or Tel number for response"
                  ></Input>
                </ModalBody>
                <ModalFooter>
                  <Button color="primary" onClick={toggle}>
                    Send message
                  </Button>{" "}
                  <Button color="secondary" onClick={toggle}>
                    Cancel
                  </Button>
                </ModalFooter>
              </Modal>
            </Card>
          </div>
        );
      })}
    </CardGroup>
  );
};

I am trying to a make Gallery application using React.JS and Reactstrap. I'm using the map() function to display every piece of art in a Card. In every card, there is a button that opens a modal to show more data from the map function. My problem is when I'm clicking the button to open modal from any card it shows the data from the last card on the page.

The code:

const Artcards = ({ state, loading }, props) => {
  const { buttonLabel, className } = props;

  const [modal, setModal] = useState(false);

  const toggle = () => setModal(!modal);



  if (loading) {
    return <h2>Loading</h2>;
  }

  return (
    <CardGroup className="CardGroup">
      {state.map((state, index) => {
        return (
          <div key={index}>
            <Card className="Card" style={{ padding: "0", height: "39rem" }}>
              <CardBody className="pt-3">
                <CardTitle className="CardTitle">
                  Art Name:
                  <h6 className="CardParagraph">{state.artName}</h6>
                </CardTitle>
                <CardSubtitle>
                  Artist Name:
                  <h6 className="CardParagraph">{state.artistName}</h6>
                </CardSubtitle>
                <CardImg
                  top
                  src={state.source}
                  alt={state.artName}
                />
              </CardBody>
              <CardBody>
                <CardText>
                  Description:
                  <div className="CardParagraph">{state.description}</div>
                </CardText>
                <CardText>
                  Price:<div className="CardParagraph">{state.price} </div>
                </CardText>
                <Button size="sm" color="danger" className=" m-1">
                  Buy
                </Button>
                <br></br>
                <Button color="success" onClick={toggle}>
                  Contact Artist
                </Button>
              </CardBody>
              <Modal
                isOpen={modal}
                state={state}
                fade={false}
                toggle={toggle}
                className={className}
              >
                <ModalHeader className="bg-dark text-primary" toggle={toggle}>
                  here the {state.artistName} should be
                </ModalHeader>
                <ModalBody>
                  <p>Header:{state.artName}</p>
                  <textarea
                    style={{ overflow: "auto", resize: "none"}}
                    rows="5"
                    cols="60"
                    placeholder="Write your message"
                  ></textarea>
                  <Input
                    type="text"
                    placeholder="Write Email or Tel number for response"
                  ></Input>
                </ModalBody>
                <ModalFooter>
                  <Button color="primary" onClick={toggle}>
                    Send message
                  </Button>{" "}
                  <Button color="secondary" onClick={toggle}>
                    Cancel
                  </Button>
                </ModalFooter>
              </Modal>
            </Card>
          </div>
        );
      })}
    </CardGroup>
  );
};
Share Improve this question edited Dec 9, 2019 at 15:06 Afia 6835 silver badges17 bronze badges asked Dec 9, 2019 at 14:36 Aviv CohenAviv Cohen 211 silver badge3 bronze badges 1
  • You're creating a modal for each card. You don't need to do that. Create one (place it under the CardGroup, for example) and toggle that instead. – Andy Commented Dec 9, 2019 at 14:40
Add a ment  | 

1 Answer 1

Reset to default 6

What you are doing here isn't opening only the last, but you are opening all modals and only the last is showing because is on top of all others.

What you need to do is have only one modal and save the index of the clicked card and then only display the data from that card.

So here is what you need to do

  1. Remove the modal from inside the .map
  2. Have another state to store the index or the data from the card
  3. Only display in the modal the data from the selected card

You also have some kind of weird use of the variable state in alot of places where you have state ming from props and then using the same name inside .map. You should change that name to something more descriptive, because this makes things very confusing.

发布评论

评论列表(0)

  1. 暂无评论