我正在使用完整的日历 API,如下所示来获取我的事件 -
<FullCalendar
ref={calendarRef}
plugins={[listPlugin, bootstrap5Plugin]}
initialView='listMonth'
themeSystem='bootstrap5'
validRange={{ "start": currentDateTime }}
headerToolbar={{
start: 'listMonth prev next',
center: 'title',
end: 'Schedule',
}}
views={
{listMonth: { buttonText: 'Month' }}
}
eventOrder={'end'}
customButtons={{
Schedule: {
text: 'Schedule Meeting',
click: function () {
handleCustomButtonClick();
}
}
}}
events={function (info, successCallback, failureCallback){
var startDateTime = info.start;
var endDateTime = info.end;
startDateTime.setMilliseconds(0);
endDateTime.setMilliseconds(0);
startDateTime = startDateTime.toISOString();
endDateTime = endDateTime.toISOString();
startDateTime = startDateTime.substring(0, startDateTime.length - 5) + 'Z';
endDateTime = endDateTime.substring(0, endDateTime.length - 5) + 'Z';
const url = `http://localhost:8080/api/meeting/abhyasi/${props.profile.googleId}/${startDateTime}/${endDateTime}`; // Use backticks for template literals
const headers = new Headers();
// Add headers to the headers object
headers.append('X-API-KEY', ",PRGojtX9`c4e24219-fb95-;'.4ed8392hfds';");
const requestOptions = {
method: 'GET',
headers: headers
};
const response = fetch(url, requestOptions)
fetch(url, requestOptions)
.then(response => {
// check if the response is a 404
if (response.status === 404) {
// if it is, then throw an error
failureCallback();
}
return response.json();
})
.then(data => {
// Handle the JSON data here
console.log(data);
// map to events object
var meeting_events = data.map((meeting) => {
return {
title: meeting.meetingAgenda,
start: meeting.startDateTime,
end: meeting.endDateTime,
extendedProps: {
startUrl: meeting.meetingStartUrl,
joinUrl: meeting.meetingJoinUrl,
meetingId: meeting.zoomMeetingId,
meetingPassword: meeting.meetingPassword
}
}
});
successCallback(meeting_events);
})
.catch(error => {
// Handle any errors that occurred during the fetch
failureCallback(error);
});
}}
eventDidMount={
function(info) {
let start = info.event.start.toISOString();
let end = info.event.end.toISOString();
let current = new Date().toISOString();
if(current < end) {
var button = document.createElement('button');
button.innerHTML = 'Delete Meeting';
button.className = 'btn btn-primary btn-sm';
button.classList.add('float-end');
button.style.marginLeft = '10px';
button.style.borderRadius = '5px';
button.style.backgroundColor = '#dc3545';
button.style.borderColor = '#dc3545';
button.addEventListener('click', function() {
deleteMeeting(info.event);
}
);
info.el.querySelector('.fc-list-event-title').appendChild(button);
}
if(start <= current && end >= current) {
var button = document.createElement('button');
button.innerHTML = 'Start';
button.className = 'btn btn-primary btn-sm';
button.classList.add('float-end');
button.style.marginLeft = '10px';
button.style.borderRadius = '5px';
button.addEventListener('click', function() {
window.open(info.event.extendedProps.startUrl);
}
);
info.el.querySelector('.fc-list-event-title').appendChild(button);
}
if(end > current) {
var button = document.createElement('button');
button.innerHTML = 'Info';
button.className = 'btn btn-primary btn-sm';
button.style.marginLeft = '10px';
button.style.borderRadius = '5px';
button.classList.add('float-end');
button.addEventListener('click', function() {
setEvent(info.event);
presentInfoModal();
}
);
// add button to the extreme right
info.el.querySelector('.fc-list-event-title').appendChild(button);
}
}
}
/>
<InfoMeetingModal />
<Modal show={showModal}>
<Modal.Header closeButton onClick={closeModal}>
<Modal.Title>Schedule Meeting</Modal.Title>
</Modal.Header>
<Modal.Body >
<Form >
<Form.Group controlId="datePicker">
<Form.Label className='form-label'>Date</Form.Label>
<DatePicker
selected={selectedDate}
onChange={handleDateChange}
dateFormat="yyyy-MM-dd"
className='form-date-picker'
/>
</Form.Group>
<Form.Group controlId="startTimePicker">
<Form.Label className='form-label'>Start Time</Form.Label>
<DatePicker
selected={selectedStartTime}
onChange={handleStartTimeChange}
showTimeSelect
showTimeSelectOnly
timeIntervals={15}
timeCaption="Start Time"
dateFormat="h:mm aa"
className='form-date-picker'
/>
</Form.Group>
<Form.Group controlId="endTimePicker">
<Form.Label className='form-label'>End Time</Form.Label>
<DatePicker
selected={selectedEndTime}
onChange={handleEndTimeChange}
showTimeSelect
showTimeSelectOnly
timeIntervals={15}
timeCaption="End Time"
dateFormat="h:mm aa"
className='form-date-picker'
/>
</Form.Group>
<Form.Group controlId="meetingDescription">
<Form.Label>Meeting Description</Form.Label>
<Form.Control
type="text"
placeholder="Enter meeting description"
value={meetingDescription}
onChange={handleDescriptionChange}
className='form-text-box'
/>
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
<Button variant="danger" onClick={closeModal}>
Close
</Button>
<Button variant="dark" onClick={createMeeting}>
Save
</Button>
<Spinner id='spinner' animation="border" role="status" hidden={!loading}> </Spinner>
</Modal.Footer>
</Modal>
</div>
);
function InfoMeetingModal() {
return (
<Modal show={showInfoModal}>
<Modal.Header closeButton onClick={closeInfoModal}>
<Modal.Title>Meeting Details</Modal.Title>
</Modal.Header>
<Modal.Body>
{
console.log(selectedEvent)
}
<div>
<p>Meeting ID: {selectedEvent.extendedProps.meetingId}</p>
<p>Meeting Password: {selectedEvent.extendedProps.meetingPassword}</p>
<p>Start Time: {
// format time to current zone in hh:mm am/pm format
new Date(selectedEvent.start).toLocaleTimeString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true })
} {currentZone}
</p>
<p>End Time: {
// format time to current zone in hh:mm am/pm format
new Date(selectedEvent.end).toLocaleTimeString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true })
} {currentZone}</p>
<p>Meeting Description: {selectedEvent.title}</p>
<div>Join Url: {selectedEvent.extendedProps.joinUrl}</div>
</div>
</Modal.Body>
</Modal>
);
}
问题是当我在下面的模式中输入日期或时间时,(通过设置状态)事件会被重新获取。
事件函数只是从我的后端服务器获取数据源。我看到一篇文章使用 useMemo 来解决这个问题。然而,我对 React 和 Web 开发还很陌生,我无法理解它(React 状态更改后,Fullcalendar 重新获取事件)
我该如何解决这个问题?
根据您的信息,我了解到问题在于传递给
events
属性的函数。现在,您已经传递了信息,并从此开始获取开始日期和结束日期,因此每次更改时,都会重新创建该函数,并且将再次获取所有事件。
您可以将函数从
events
属性移动到 useMemo
钩子内,并将信息作为解决方案的依赖项。