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

如何使用多个React-Bootstrap模态框?解决弹窗数据重复问题

解决React-Bootstrap动态生成模态框数据显示错误问题

问题场景

通过映射数组数据生成多个React-Bootstrap模态框,但点击任意弹窗后,所有模态框均显示数组最后一项的数据,需要实现每个弹窗展示对应项的不同数据。

问题原因

  1. 状态共享冲突:所有模态框共用同一个modalShow布尔状态,当状态切换为true时,所有模态框都会同时显示;再加上循环闭包特性,最终所有模态框的props都会绑定到数组最后一项的数据。
  2. 混用原生Bootstrap属性:按钮上添加了data-bs-toggle和data-bs-target这类Bootstrap原生模态框触发属性,和React的状态管理逻辑冲突,干扰了模态框的正确渲染。

解决方案

方案一:用唯一标识控制单个模态框显示

将全局布尔状态改为存储当前激活模态框的唯一标识(比如数组项中的mod字段),精准控制对应模态框的显示:

const Leadershipcard = (prop: props) => {
    // 存储当前激活模态框的mod值,初始为null表示无弹窗打开
    const [activeModal, setActiveModal] = useState<string | null>(null)
    
    return (
        <>
            {content.map((e) =>
                <div className="card col-lg-6 p-0" style={{ "width": "18rem" } as React.CSSProperties} key={e.mod}>
                    <img src={`Assets\\About\\team\\${e.cardimg}.webp`} className="card-img-top" alt={`${e.Name}的照片`} />
                    <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={() => setActiveModal(e.mod)}
                        >查看更多</button>
                        <Modals
                            show={activeModal === e.mod}
                            onHide={() => setActiveModal(null)}
                            Img={e.cardimg}
                            Name={e.Name}
                            Post={e.Post}
                            Nation={e.Nation}
                            About={e.About}
                            mod={e.mod}
                        />
                    </div>
                </div>
            )}
        </>
    )
}

export default Leadershipcard

修改说明:

  • 用activeModal存储当前要打开的模态框唯一标识,替代原来的布尔状态,实现精准控制。
  • 移除按钮上的data-bs-toggle和data-bs-target属性,完全由React状态管理模态框显示。
  • 模态框的show属性通过判断activeModal是否等于当前项的mod来决定是否显示。
  • 为列表项添加key属性,符合React列表渲染的性能优化要求。

方案二:抽离独立子组件

将每个卡片与对应的模态框封装成独立子组件,使每个组件拥有专属的状态,避免状态共享问题:

// 独立子组件:单个领导卡片+模态框
const LeadershipItem = ({ item }: { item: typeof content[0] }) => {
    const [modalShow, setModalShow] = useState(false)
    
    return (
        <div className="card col-lg-6 p-0" style={{ "width": "18rem" } as React.CSSProperties}>
            <img src={`Assets\\About\\team\\${item.cardimg}.webp`} className="card-img-top" alt={`${item.Name}的照片`} />
            <div className="card-body">
                <h5 className="card-title">{item.Name}</h5>
                <p className="card-text">{item.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)}
                >查看更多</button>
                <Modals
                    show={modalShow}
                    onHide={() => setModalShow(false)}
                    Img={item.cardimg}
                    Name={item.Name}
                    Post={item.Post}
                    Nation={item.Nation}
                    About={item.About}
                    mod={item.mod}
                />
            </div>
        </div>
    )
}

// 原父组件
const Leadershipcard = (prop: props) => {
    return (
        <>
            {content.map((e) => <LeadershipItem key={e.mod} item={e} />)}
        </>
    )
}

export default Leadershipcard

优势:

  • 每个子组件拥有独立的modalShow状态,互不干扰,彻底解决状态共享导致的数据错误。
  • 代码结构更清晰,符合React组件拆分的最佳实践,便于后续维护和扩展。

内容的提问来源于stack exchange,提问作者Nakul Soral

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:52:56