You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 05:55:23