我正在尝试使用 Full Calendar 和 Elastic Ui 构建一个日历应用程序,我使用状态来管理数据/事件输入,使用表单将事件添加到日历,并选择日历上的日期也会更新表单值。该应用程序现在部分工作,我可以将事件输入日历,但只有在我从日历中选择/单击日期之后,表格才能正常工作。但是,如果我在单击日历之前在表单中的文本字段或日期选择器上输入,则会出现以下错误并且整个页面变为空白。
超过最大更新深度。
上述错误发生在 DatePicker 组件中:
无法对未安装的组件执行 React 状态更新。
有人知道发生了什么吗?或者我怎样才能找到问题的根源?
webapp第一次加载时也有两个错误:
index.js:1 警告:无法在尚未安装的组件上调用 setState。这是一个无操作,但它可能表明您的应用程序中存在错误。相反,在 EuiIcon 组件中
this.state
直接分配或定义state = {};
具有所需状态的类属性。安慰。@
index.js:1 警告:无法在尚未安装的组件上调用 setState。这是一个无操作,但它可能表明您的应用程序中存在错误。相反,在 CalendarDataProvider 组件中直接分配
this.state
或定义state = {};
具有所需状态的类属性。
import React, { Component, useState } from 'react';
import FullCalendar from '@fullcalendar/react'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from "@fullcalendar/interaction"
import googleCalendarPlugin from '@fullcalendar/google-calendar'
import moment from 'moment'
import {EuiFlexGroup, EuiFlexItem, EuiFieldText, EuiForm, EuiFormRow, EuiButton, EuiSwitch,
EuiDatePicker, EuiDatePickerRange, EuiRadioGroup
} from '@elastic/eui'
require('dotenv').config()
const AddEventBar = (props) => {
const [isDisabled, setDisabled] = useState(false)
const [StartRepeatDate, setStartRepeatDate] = useState(null)
const [EndRepeatDate, setEndRepeatDate] = useState(null)
const [radioIdSelected, setRadioIdSelected] = useState(null);
const handleChangeStart = (date) => {
setStartRepeatDate(date)
}
const handleChangeEnd = (date) => {
setEndRepeatDate(date)
}
const radioHandler = (optionId) => {
setRadioIdSelected(optionId);
};
const radios = [
{
id: 'daily',
label: 'daily',
},
{
id: 'weekly',
label: 'weekly',
},
];
return (
<EuiFlexGroup>
<EuiFlexItem>
<EuiForm>
<EuiFormRow label='Event Title'>
<EuiFieldText
onChange={props.titleHandler}
aria-label="Use aria labels when no actual label is in use"
/>
</EuiFormRow>
<EuiFormRow label = 'Event Date'>
<EuiDatePicker
placeholder='Start'
selected={moment(props.start_date)}
onChange={props.startDatePickerHandler}
aria-label="Start date"
/>
</EuiFormRow>
<EuiFormRow label='Event Time'>
<EuiDatePickerRange
startDateControl = {
<EuiDatePicker
showTimeSelect
showTimeSelectOnly
selected={moment(props.start_date + ' ' + props.start_time)}
onChange={props.startDatePickerHandler}
timeFormat="hh:mm a"
dateFormat="hh:mm a"
/>}
endDateControl = {
<EuiDatePicker
showTimeSelect
showTimeSelectOnly
selected={moment(props.start_date + ' ' + props.end_time)}
onChange={props.endDatePickerHandler}
timeFormat="hh:mm a"
dateFormat="hh:mm a"
/>
}
>
</EuiDatePickerRange>
</EuiFormRow>
<EuiFormRow>
<EuiSwitch
label="Repeat Event"
checked={isDisabled}
onChange={(e) => setDisabled(e.target.checked)}
/>
</EuiFormRow>
<EuiFormRow>
<EuiDatePickerRange
startDateControl={
<EuiDatePicker
placeholder='Start'
disabled={!isDisabled}
selected={StartRepeatDate}
onChange={handleChangeStart}
startDate={StartRepeatDate}
endDate={EndRepeatDate}
isInvalid={StartRepeatDate > EndRepeatDate}
aria-label="Start date"
/>
}
endDateControl={
<EuiDatePicker
placeholder='End'
disabled={!isDisabled}
selected={EndRepeatDate}
onChange={handleChangeEnd}
startDate={StartRepeatDate}
endDate={EndRepeatDate}
isInvalid={StartRepeatDate > EndRepeatDate}
aria-label="End date"
/>
}
/>
</EuiFormRow>
<EuiFormRow>
<EuiRadioGroup
disabled={!isDisabled}
options={radios}
idSelected={radioIdSelected}
onChange={(id) => radioHandler(id)}
name="radio group"
/>
</EuiFormRow>
<EuiFormRow>
<EuiButton onClick={props.addEventHandler} type='submit'>
Add Event
</EuiButton>
</EuiFormRow>
</EuiForm>
</EuiFlexItem>
</EuiFlexGroup>
)
}
class Calendar extends Component {
state = {
selectInfo: null,
// dateClickInfo: null,
allDay: false,
title: null,
start_date: moment(),
end_date: moment(),
start_time: null,
end_time: null,
}
addEventHandler = (state) => {
if(this.state.title === null){
alert('Please enter title')
}
else if(this.state.selectInfo === null){
alert('Please select event date')
}
else {
if(this.state.start_time || this.state.end_time){
let calendarApi = this.state.selectInfo.view.calendar
calendarApi.addEvent({
title: this.state.title,
id: new Date(),
start: this.state.start_date.concat('T', this.state.start_time),
end: this.state.end_date.concat('T', this.state.end_time),
})
} else {
let calendarApi = this.state.selectInfo.view.calendar
calendarApi.addEvent({
title: this.state.title,
id: new Date(),
start: this.state.start_date,
end: this.state.end_date,
allDay: this.state.selectInfo.allDay,
})
}
}
}
titleHandler = (title) => {
const titleValue = title.target.value
this.setState({title: titleValue})
}
startDatePickerHandler = (date) => {
// date is moment object
const startDate = date.format().slice(0, 10)
const startTime = date.format().slice(11, 16)
// console.log('start date:' + startDate + ', start time:' + startTime)
this.setState({start_date: startDate, start_time: startTime})
}
endDatePickerHandler = (date) => {
// date is moment object
const endDate = date.format().slice(0, 10)
const endTime = date.format().slice(11, 16)
// console.log('end date:' + endDate + ', end time:' + endTime)
this.setState({end_date: endDate, end_time: endTime})
}
handleEventClick = (clickInfo) => {
if (window.confirm(`Are you sure you want to delete the event '${clickInfo.event.title}'`)) {
clickInfo.event.remove()
}
}
handleDateSelect = (selectInfo) => {
let calendarApi = selectInfo.view.calendar
calendarApi.unselect() // clear date selection
if(selectInfo) {
if (selectInfo.startStr.length >= 10){
const startStr = selectInfo.startStr.slice(0, 10)
const endStr = selectInfo.endStr.slice(0, 10)
const startTime = selectInfo.startStr.slice(11, 16)
const endTime = selectInfo.endStr.slice(11, 16)
this.setState({selectInfo: selectInfo, start_date: startStr, end_date: endStr, start_time: startTime, end_time: endTime})
} else {
this.setState({selectInfo: selectInfo, start_date:selectInfo.startStr, end_date: selectInfo.endStr})
}
}
}
render() {
return (
<EuiFlexGroup direction='row'>
<EuiFlexItem grow={6}>
<FullCalendar
plugins={[ dayGridPlugin, interactionPlugin, timeGridPlugin, googleCalendarPlugin ]}
googleCalendarApiKey = {process.env.REACT_APP_API_KEY}
events = {{
googleCalendarId: process.env.REACT_APP_GOOGLE_CALENDAR_ID
}}
headerToolbar={{
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
}}
initialView="dayGridMonth"
selectable={true}
editable={true}
expandRows={true}
select={this.handleDateSelect}
// dateClick={dateClickHandler}
eventClick={this.handleEventClick}
/>
</EuiFlexItem>
<EuiFlexItem grow={3}>
<AddEventBar
title={this.state.title}
start_date={this.state.start_date}
end_date={this.state.end_date}
start_time={this.state.start_time}
end_time={this.state.end_time}
titleHandler={this.titleHandler}
addEventHandler={this.addEventHandler}
startDatePickerHandler={this.startDatePickerHandler}
endDatePickerHandler={this.endDatePickerHandler}
></AddEventBar>
</EuiFlexItem>
</EuiFlexGroup>
)
}}
export default Calendar