React组件中Bootstrap模态框无法正确获取映射状态值的问题
问题分析与解决方案
这问题我太熟了!你遇到的核心问题是所有模态框都使用了同一个id="exampleModal"。
Bootstrap 的模态框是通过 data-bs-target 属性指定的 ID 来匹配对应弹窗的。当页面上存在多个拥有相同 ID 的元素时,浏览器只会找到第一个匹配的元素——也就是你循环生成的第一个(对应 value=0)模态框,所以不管你点击哪个按钮,打开的都是这同一个弹窗,自然显示的永远是0。
解决方法一:给每个模态框设置唯一ID
最简单的修复方式就是给每个模态框和对应的按钮生成唯一的标识,比如把 ID 和循环的 value 绑定:
修改后的完整代码如下:
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css"; import React from "../../node_modules/react"; function Comp(props) { return [0, 1, 2, 3, 4, 5].map(value => ( <> {/* 按钮的data-bs-target对应唯一的模态框ID */} <button type="button" className="btn btn-success m-2" data-bs-toggle="modal" data-bs-target={`#exampleModal-${value}`} > {`Click button ${value} to open below Modal`} </button> {/* 模态框的ID加上value后缀,保证唯一 */} <div className="modal fade text-white" id={`exampleModal-${value}`} data-bs-backdrop="static" tabindex="-1" aria-labelledby={`exampleModalLabel-${value}`} aria-hidden="true" > <div className="modal-dialog"> <div className="modal-content bg-dark"> <div className="modal-header"> <h5 className="modal-title" id={`exampleModalLabel-${value}`} > Show value </h5> <button type="button" className="btn-close btn-close-white btn-sm" data-bs-dismiss="modal" aria-label="Close" ></button> </div> <div className="modal-body"> <form> <div className="mb-3"> <h1 className="text-white">{value}</h1> </div> </form> </div> </div> </div> </div> </> )); } export default Comp;
这里我还顺便把所有的 class 改成了 React 推荐的 className(虽然原生HTML的class在JSX里也能运行,但用className是规范写法),同时把模态框的 aria-labelledby 也改成了对应的唯一ID,保证 accessibility 合规。
更优的解决方法:复用单个模态框
其实不需要生成6个模态框,我们可以只做一个弹窗,点击按钮时动态更新弹窗里的内容,这样能减少DOM元素,性能更好:
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css"; import React, { useState, useRef } from "../../node_modules/react"; import { Modal } from 'bootstrap'; // 引入Bootstrap的Modal类 function Comp(props) { const [currentValue, setCurrentValue] = useState(0); const modalRef = useRef(null); let modalInstance = null; // 初始化模态框实例 React.useEffect(() => { modalInstance = new Modal(modalRef.current); return () => { modalInstance.dispose(); }; }, []); const openModal = (value) => { setCurrentValue(value); modalInstance.show(); }; return ( <> {[0, 1, 2, 3, 4, 5].map(value => ( <button key={value} type="button" className="btn btn-success m-2" onClick={() => openModal(value)} > {`Click button ${value} to open below Modal`} </button> ))} {/* 唯一的模态框 */} <div ref={modalRef} className="modal fade text-white" id="exampleModal" data-bs-backdrop="static" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true" > <div className="modal-dialog"> <div className="modal-content bg-dark"> <div className="modal-header"> <h5 className="modal-title" id="exampleModalLabel">Show value</h5> <button type="button" className="btn-close btn-close-white btn-sm" data-bs-dismiss="modal" aria-label="Close" ></button> </div> <div className="modal-body"> <form> <div className="mb-3"> <h1 className="text-white">{currentValue}</h1> </div> </form> </div> </div> </div> </div> </> ); } export default Comp;
这种方式通过React的状态来控制模态框显示的值,只渲染一个模态框,不仅代码更简洁,还避免了重复DOM节点的问题,推荐使用这种方式。
内容的提问来源于stack exchange,提问作者kaushalpranav
相关产品推荐
相关产品推荐

