React中点击FullCalendar日期打开Bootstrap5模态框的问题
解决React中FullCalendar点击日期打开Bootstrap 5模态框的问题
核心问题分析
- Bootstrap 5无需jQuery:你完全不需要导入jQuery,Bootstrap 5已改用原生JavaScript实现组件功能,这也是你遇到
$ is not a function错误的根本原因。 - useRef使用错误:原代码中
modalRef..toggle()存在语法错误(双点),且未正确初始化Bootstrap Modal实例。 - 条件渲染限制:通过
{showModal && (...)渲染模态框会导致DOM元素仅在showModal为true时存在,无法可靠通过Bootstrap API控制组件状态。
修正后的代码实现
import { useState, useRef, useEffect } from 'react'; import FullCalendar from '@fullcalendar/react'; import dayGridPlugin from '@fullcalendar/daygrid'; import interactionPlugin from '@fullcalendar/interaction'; import esLocale from '@fullcalendar/core/locales/es'; const CalendarContainerPage = () => { const modalRef = useRef(null); const [showModal, setShowModal] = useState(false); let bootstrapModal = null; // 存储Bootstrap Modal实例 // 初始化Bootstrap Modal并绑定关闭事件 useEffect(() => { if (modalRef.current) { bootstrapModal = new window.bootstrap.Modal(modalRef.current); // 监听模态框关闭事件,同步React状态 modalRef.current.addEventListener('hidden.bs.modal', () => { setShowModal(false); }); } // 组件卸载时销毁模态框实例,避免内存泄漏 return () => { if (bootstrapModal) { bootstrapModal.dispose(); } }; }, []); // 根据React状态控制模态框显示/隐藏 useEffect(() => { if (bootstrapModal) { showModal ? bootstrapModal.show() : bootstrapModal.hide(); } }, [showModal]); const handleDayClick = (info) => { console.log('选中日期:', info.start.toISOString().split('T')[0]); setShowModal(true); }; const handleCloseModal = () => { setShowModal(false); }; const randomColor = "#" + ((1 << 24) * Math.random() | 0).toString(16); const eventObject = [ { groupId: 'blueEvents', title: 'Congress', start: '2023-06-21', end: '2023-06-22', startRecur: '2023-06-18T09:00:00', endRecur: '2023-06-29T18:00:00', startTime: '12:30:00', endTime: '13:30:00', daysOfWeek: ['1', '2'], display: 'block', color: randomColor, } ]; const eventClick = (info) => { alert('事件: ' + info.event.title); }; return ( <div className='calendarBoard'> <FullCalendar plugins={[dayGridPlugin, interactionPlugin]} locale={esLocale} initialView="dayGridMonth" height='100%' selectable={true} select={handleDayClick} events={eventObject} eventClick={eventClick} handleWindowResize={true} /> {/* 始终保持模态框在DOM中,通过Bootstrap API控制显示状态 */} <div className="modal fade" ref={modalRef} id="ModalDay" tabindex="-1" aria-labelledby="ModalDayLabel" aria-hidden="true" > <div className="modal-dialog"> <div className="modal-content"> <div className="modal-header"> <h5 className="modal-title" id="ModalDayLabel">日期详情</h5> <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close" ></button> </div> <div className="modal-body px-4"> 这里可以添加选中日期的自定义内容 </div> <div className="modal-footer"> <button type="button" className="btn btn-secondary" data-bs-dismiss="modal" onClick={handleCloseModal} > 关闭 </button> <button type="button" className="btn btn-primary">保存更改</button> </div> </div> </div> </div> </div> ); }; export default CalendarContainerPage;
关键修正点说明
- 移除jQuery依赖:直接使用Bootstrap 5原生的
Modal类初始化模态框,无需引入jQuery。 - 固定模态框DOM存在性:不再通过条件渲染控制模态框的存在,始终保留在DOM中,解决初始化时找不到元素的问题。
- 同步React状态与Bootstrap模态框:监听模态框的
hidden.bs.modal事件,确保用户通过原生按钮关闭模态框时,React状态也同步更新。 - 正确使用useRef:通过
modalRef.current获取DOM元素,初始化Bootstrap Modal实例,并在组件卸载时销毁实例防止内存泄漏。 - 完善FullCalendar事件处理:
handleDayClick接收FullCalendar的info参数,可直接获取选中的日期信息供后续使用。
内容的提问来源于stack exchange,提问作者Mariel Alejandra
相关产品推荐
相关产品推荐

