React遍历对象数组时所有Modal同时弹出的问题解决
修复React卡片点击触发所有Modal弹出的问题
你的代码问题出在单个布尔状态showModal控制了所有Modal的显示,点击卡片时这个状态变为true,所有绑定了show={showModal}的Modal都会弹出,而视觉上最后一个Modal会覆盖前面的,所以看起来只显示最后一个的内容。同时你没有关联点击的卡片对应的项目数据,无法实现对应内容的展示。
核心修改点
- 将状态从布尔值改为存储当前打开的项目ID(初始为
null),通过ID关联卡片和对应的Modal - 让
handleShow接收项目ID参数,点击卡片时设置当前激活的ID - 每个Modal的
show属性判断当前项目ID是否与自身ID匹配 - 优化代码结构,将卡片和对应的Modal放在同一个循环中,避免两次遍历数组
修改后的完整代码
// import projects into portfolio import React, { useState } from 'react'; // react bootstrap imports import Modal from 'react-bootstrap/Modal'; import Button from 'react-bootstrap/Button'; const projectData = [ { id: 1, name: 'Project 1', photo: project1, url: 'https://', gitHub: 'https://', summary: 'Lorem ipsum', techSkills: 'abc' }, { id: 2, name: 'Project 2', photo: project2, url: 'https://', gitHub: 'https://', summary: 'Lorem ipsum', techSkills: 'abc' }, { id: 3, name: 'Project 3', url: 'https://', photo: project3, gitHub: 'https://', summary: 'Lorem ipsum', techSkills: 'abc' }, { id: 4, name: 'Project 4', url: 'https://', photo: project4, gitHub: 'https://', summary: 'lorem ipsum', techSkills: 'abc' } ]; function Project(props) { // 用状态存储当前打开的项目ID,初始为null表示没有Modal打开 const [activeModalId, setActiveModalId] = useState(null); // 关闭Modal时重置为null const handleClose = () => setActiveModalId(null); // 打开Modal时传入对应的项目ID const handleShow = (projectId) => setActiveModalId(projectId); return ( <div className='container'> <div className='row'> {projectData.map((data) => { const { id, name, photo, summary, techSkills, url, gitHub } = data; return ( <div className='col-3 d-flex mb-4' key={id}> {/* 点击时传入当前项目ID */} <Button onClick={() => handleShow(id)} className="project-card card p-0 border-5 border-dark shadow-lg"> <img className='card-img shadow-lg' src={photo} alt={name} /> </Button> {/* 同一个循环内渲染对应项目的Modal */} <Modal {...props} size="lg" aria-labelledby="contained-modal-title-vcenter" centered // 仅当当前项目ID等于activeModalId时显示 show={activeModalId === id} onHide={handleClose} key={id} > <Modal.Header closeButton className="border-dark"> <Modal.Title className="" id="modal-title"> {name} </Modal.Title> </Modal.Header> <Modal.Body className="container"> <p>{summary}</p> <br /> <p>{techSkills}</p> </Modal.Body> <Modal.Footer className="modal-bg border-dark"> {/* 移除重复ID,改用类名保证HTML规范 */} <Button className="modal-button" target='_blank' rel='noreferrer' href={url}>View live app here!</Button> <Button className="modal-button" target='_blank' rel='noreferrer' href={gitHub}> <span className='bi bi-github work-icon'></span> </Button> </Modal.Footer> </Modal> </div> ); })} </div> </div> ); }
额外优化说明
- 移除了重复的
id="modal-button",因为HTML中ID必须唯一,改用类名modal-button - 将卡片和Modal放在同一个循环中,代码更简洁,避免不必要的数组遍历
- 通过项目ID精确控制单个Modal的显示,彻底解决所有Modal同时弹出的问题
内容的提问来源于stack exchange,提问作者Maggie
相关产品推荐
相关产品推荐

