React-Bootstrap 模态只取地图的最后一项



我是编码初学者。我正在创建我的平面设计师作品集。我已将所有投资组合内容(缩略图,客户端名称,描述...(放入JSON文件中名为"投资组合"的数组中。数组中的每个项目都是一个不同的项目。我显示了一系列缩略图,当我单击缩略图时,将打开一个包含项目详细信息的模式。

我在我的"投资组合"阵列上映射以显示画廊,这有效。但是当我打开模态时,它总是显示数组的最后一项。

import React from 'react';
import Modal from 'react-bootstrap/Modal';
class Portfolio extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      error: null,
      isLoaded: false,
      items: [],
      projectName: "",
      show: false
    };
    this.handleShow = () => {
      this.setState({ show: true });
    };
    this.handleClose = () => {
      this.setState({ show: false });
    };
  }
  componentDidMount() {
    fetch("https://api.myjson.com/bins/1cbaj5")
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            items: result.portfolio
          });
        },
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }
    
  render() {
    const {error, isLoaded, items} = this.state;
    if (error) {
      return <div>Erreur : {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Chargement…</div>;
    } else {
      return (
        <div id="portfolio">
          <h2>Portfolio</h2>
          <ul className="portfolio-list">
            {items.map(item => (
              <li key={item.client}>
                <div className="vignette">
                  <button onClick={() => this.handleShow()}>
                    <h4>{item.client}</h4>
                    <div className="filtre"></div>
                    <img src={item.vignette} alt={item.titre} />
                  </button>
                  <Modal show={this.state.show} onHide={this.handleClose}>
                    <Modal.Header closeButton>
                      <h3>{item.client}</h3>
                    </Modal.Header>
                    <Modal.Body>
                      <p>{item.description}</p>
                    </Modal.Body>
                  </Modal>
                </div>
              </li>
            ))}
          </ul>
        </div>
      );
    }
  }
}
export default Portfolio;

我希望模态显示相应的项目详细信息。谢谢你的帮助。

您只需要 1 个模态并在单击item动态传递数据,

<ul className="portfolio-list">
    {items.map(item => (
    <li key={item.client}>
        <div className="vignette">
            <button onClick={()=> this.handleShow(item)}> //Pass complete item object here
                <h4>{item.client}</h4>
                <div className="filtre"></div>
                <img src={item.vignette} alt={item.titre} />
            </button>
        </div>
    </li>
    ))}
    <Modal show={this.state.show} onHide={this.handleClose}> //Only one modal
        <Modal.Header closeButton>
            <h3>{this.state.activeItem.client}</h3>
        </Modal.Header>
        <Modal.Body>
            <p>{this.state.activeItem.description}</p>
        </Modal.Body>
    </Modal>
</ul>

现在,在handleShow函数中,您可以将item设置为状态,

this.handleShow = (item) => {
   this.setState({activeItem:item}, ()=> this.setState({ show: true }));
};

使用callback显示模态,以确保activeItem具有最近单击的item

初始状态,

this.state = {
   error: null,
   isLoaded: false,
   items: [],
   projectName: "",
   show: false,
   activeItem:'' //new added
};

前面的答案很棒。在功能组件中,可以创建一个用于处理这两种状态的函数,并且它完美地工作。

    export const TeamCollection = () => {
  const [modalShow, setModalShow] = useState(false);
  const [name, setName] = useState("");
  const handleName = (name) => {
    setName(name);
    setModalShow(true);
  };
  return (
    <Container>
      <Row>
        {team_data.map((item) => (
          <Col key={item.id}>
            <div style={{ width: "175px" }}>
              <ImageContainer>
                <LinkContainer onClick={() => handleName(item.name)}>
                  <BackgroundImage
                    style={{ backgroundImage: `url(${item.imageUrl})` }}
                  />
                </LinkContainer>
              </ImageContainer>
              <h4>{item.name}</h4>
              <p>{item.position}</p>
            </div>
          </Col>
        ))}
      </Row>
      <RouteModal
        data={name}
        show={modalShow}
        onHide={() => setModalShow(false)}
      />
    </Container>
  );
};
export default TeamCollection;

最新更新