React 16中监听Bootstrap 4模态框关闭事件并重置数据
在React 16 + Bootstrap 4中监听模态框关闭并重置数据
嘿,这个场景我太熟了!既然你已经把模态框封装成独立组件,而且不想引入额外库,那咱们就用React的生命周期/钩子结合Bootstrap原生事件来搞定,完全不用全局jQuery选择器影响其他组件~
核心思路是:在模态框组件内部,通过React的ref绑定到模态框DOM元素,然后监听Bootstrap的hidden.bs.modal事件(这个事件会在模态框完全关闭,包括动画结束后触发),在事件回调里重置组件内部的数据。
下面分两种组件类型给出实现方案:
1. Class组件实现
如果你的模态框是Class组件,可以用componentDidMount绑定事件,componentWillUnmount解绑事件防止内存泄漏:
import React, { Component } from 'react'; class CustomModal extends Component { constructor(props) { super(props); // 初始化模态框数据 this.state = { modalFormData: { name: '', email: '' // 你的其他数据字段 } }; // 创建ref指向模态框根元素 this.modalRef = React.createRef(); this.handleModalClose = this.handleModalClose.bind(this); } componentDidMount() { // 绑定Bootstrap模态框关闭事件 $(this.modalRef.current).on('hidden.bs.modal', this.handleModalClose); } componentWillUnmount() { // 组件卸载时解绑事件,避免内存泄漏 $(this.modalRef.current).off('hidden.bs.modal', this.handleModalClose); } handleModalClose() { // 重置数据到初始状态 this.setState({ modalFormData: { name: '', email: '' } }); // 如果你需要通知父组件模态框已关闭,也可以调用父组件传递的回调 // this.props.onModalClosed(); } render() { const { modalFormData } = this.state; return ( <div ref={this.modalRef} className="modal fade" tabIndex="-1" role="dialog"> <div className="modal-dialog" role="document"> <div className="modal-content"> <div className="modal-header"> <h5 className="modal-title">模态框标题</h5> <button type="button" className="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div className="modal-body"> {/* 这里展示你的数据/表单 */} <div className="form-group"> <label>姓名</label> <input type="text" className="form-control" value={modalFormData.name} onChange={(e) => this.setState({ modalFormData: {...modalFormData, name: e.target.value} })} /> </div> <div className="form-group"> <label>邮箱</label> <input type="email" className="form-control" value={modalFormData.email} onChange={(e) => this.setState({ modalFormData: {...modalFormData, email: e.target.value} })} /> </div> </div> <div className="modal-footer"> <button type="button" className="btn btn-secondary" data-dismiss="modal">关闭</button> <button type="button" className="btn btn-primary">保存</button> </div> </div> </div> </div> ); } } export default CustomModal;
2. Function组件实现(React 16.8+)
如果是用Function组件+Hook,那就用useRef获取模态框元素,useEffect绑定和解绑事件:
import React, { useState, useRef, useEffect } from 'react'; const CustomModal = () => { // 初始化模态框数据 const [modalFormData, setModalFormData] = useState({ name: '', email: '' }); // 创建ref指向模态框根元素 const modalRef = useRef(null); const handleModalClose = () => { // 重置数据到初始状态 setModalFormData({ name: '', email: '' }); // 可选:通知父组件 // props.onModalClosed(); }; useEffect(() => { const modalElement = modalRef.current; // 绑定关闭事件 $(modalElement).on('hidden.bs.modal', handleModalClose); // 清理函数:组件卸载时解绑事件 return () => { $(modalElement).off('hidden.bs.modal', handleModalClose); }; }, []); // 空依赖数组,确保只在组件挂载/卸载时执行一次 return ( <div ref={modalRef} className="modal fade" tabIndex="-1" role="dialog"> <div className="modal-dialog" role="document"> <div className="modal-content"> <div className="modal-header"> <h5 className="modal-title">模态框标题</h5> <button type="button" className="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div className="modal-body"> <div className="form-group"> <label>姓名</label> <input type="text" className="form-control" value={modalFormData.name} onChange={(e) => setModalFormData(prev => ({...prev, name: e.target.value}))} /> </div> <div className="form-group"> <label>邮箱</label> <input type="email" className="form-control" value={modalFormData.email} onChange={(e) => setModalFormData(prev => ({...prev, email: e.target.value}))} /> </div> </div> <div className="modal-footer"> <button type="button" className="btn btn-secondary" data-dismiss="modal">关闭</button> <button type="button" className="btn btn-primary">保存</button> </div> </div> </div> </div> ); }; export default CustomModal;
关键注意事项
- 确保jQuery和Bootstrap JS已引入:因为Bootstrap的模态框功能依赖jQuery,所以你的项目里必须已经加载了这两个库(可以通过CDN或者npm安装后引入)。
- 避免全局选择器:用
ref绑定到当前组件的模态框元素,而不是用$(".modal")全局选择,这样只会监听当前组件的模态框事件,不会影响页面上其他的Bootstrap模态框。 - 必须解绑事件:不管是Class组件的
componentWillUnmount还是Function组件的useEffect清理函数,一定要解绑事件,防止内存泄漏。 - 事件时机:
hidden.bs.modal是模态框完全关闭(包括动画结束)后触发的,如果你需要在开始关闭时触发,可以用hide.bs.modal事件,但通常重置数据用hidden.bs.modal更合适。
内容的提问来源于stack exchange,提问作者Ricks
相关产品推荐
相关产品推荐

