React+TypeScript动态Bootstrap手风琴仅首个可触发模态框如何解决
问题根因
- 传递参数错误:所有
<EditRestaurantFunction />组件接收的都是全局状态deckId,而非当前手风琴对应的固定ID。每次点击任意手风琴更新全局deckId时,所有组件的模态框ID、按钮触发目标都会同步修改,导致ID重复冲突,只有第一个生效。 - Bootstrap原生事件绑定限制:Bootstrap仅在页面首次加载完成时扫描DOM中的
data-bs-*属性绑定事件,手风琴折叠状态下内部DOM处于隐藏状态,不会被扫描到,因此动态渲染/隐藏的元素绑定的data-bs-toggle不会生效。 - 固定ID冲突:模态框内部的
kt_modal_create_app_stepper、kt_modal_create_cabin_benefits_form等ID是固定值,渲染多个组件时出现重复ID,也会导致交互异常。
解决方案
第一步:修正组件传参
把手风琴组件中调用<EditRestaurantFunction />的传参修改为当前手风琴项的ID,而非全局状态:
// 原来的写法 <EditRestaurantFunction deckId={deckId} // 其他参数不变 /> // 修改为 <EditRestaurantFunction deckId={d.id} // 其他参数不变 />
这样每个组件的模态框ID、触发目标都是对应手风琴的固定值,不会出现全局更新导致的ID冲突。
第二步:改用Bootstrap JS API手动控制模态框
放弃data-bs-toggle、data-bs-target属性,手动调用Bootstrap模态框API触发显示,适配动态渲染场景:
- 首先在
EditRestaurantFunction组件顶部导入Bootstrap Modal:
import { Modal } from 'bootstrap'
- 给模态框添加ref引用,删除按钮上的
data-bs-toggle、data-bs-target属性,修改点击事件:
const EditRestaurantFunction = (props) => { // 新增模态框ref const modalRef = useRef(null); // 其他原有逻辑不变 return ( <div className="col-md-auto"> <button type='button' className='btn btn-warning' onClick={() => { ifHasThenChecked(); // 手动触发模态框显示 const modalEle = modalRef.current; const modalInstance = Modal.getInstance(modalEle) || new Modal(modalEle); modalInstance.show(); }} > {intl.formatMessage({ id: 'EDIT' })} </button> </div> {/* 给模态框添加ref */} <div className="modal fade" tabIndex={-1} id={'editRestaurants' + props.deckId} ref={modalRef}> {/* 模态框原有内容不变 */} </div> ) }
第三步:修正内部重复ID
将模态框内部的固定ID都加上deckId后缀,避免多个组件之间ID冲突:
// 示例修改 <div ref={stepperRef} className='stepper stepper-pills stepper-column d-flex flex-column flex-xl-row flex-row-fluid' id={`kt_modal_create_app_stepper_${props.deckId}`} > <Form className='form' noValidate id={`kt_modal_create_cabin_benefits_form_${props.deckId}`}> <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close" id={`closeButtonEditRestaurantDeck_${props.deckId}`} >
内容的提问来源于stack exchange,提问作者malthe.w
相关产品推荐
相关产品推荐

