我的代码结构如下: 渲染功能 返回我组件的jsx主体的函数 带有null的state.popup,在单击按钮时会用JSX更新
inside state.popup我有一个带有输入和自定义日期选择器的表单。当使用onClick单击图标时,应该显示自定义日期选择器。当onClick运行时,我将this.state.dateSelector设置为state.popup JSX内的JSX,但是dateSelector不会呈现。
import React, { Component } from 'react';
import calendarData from './DataHandling';
//CSS
import './Calendar.css';
class Calendar extends Component {
constructor(props) {
super(props);
this.state = {
popup: [],
miniCalendar: [],
create: {
title: undefined,
startTime: undefined,
endTime: undefined,
date: undefined,
month: undefined,
year: undefined
},
};
this.calendarBody = React.createRef();
this.popup = React.createRef();
this.createPopup = React.createRef();
this.closeX = React.createRef();
this.dateSelectorHolder = React.createRef();
this.daySelect = React.createRef();
this.monthSelect = React.createRef();
this.yearSelect = React.createRef();
this.resetDate = this.resetDate.bind(this);
this.createEvent = this.createEvent.bind(this)
};
// -- Popup related code --
closePopup = (e) => {
if(!e.path.includes(this.popup.current) && !e.path.includes(this.createPopup.current) || e.path.includes(this.closeX.current) || e.path.includes(this.dateSelectorHolder.current)) {
console.log('sjasfafä');
this.setState({
popup: null,
miniCalendar: null
});
document.body.removeEventListener('click', this.closePopup);
};
};
// createEvent is used to create an new event in the calendar
createEvent = () => {
let elements = (
<div className="poupContainer" >
<div className="popup createPopup" ref={ this.popup }>
<div className="createHeader">
<span>Create New Event</span>
<div ref={ this.closeX } className="closeX">╳</div>
</div>
<div className="createBody">
<form onSubmit={ this.createSubmitted } >
<span className="createLabel createTitle">
<label>Title</label>
<input
type="text"
name="title"
value={ this.state.create.title }
onChange={ this.createHandler }
placeholder='Title'
autoComplete="off"
/>
</span>
<span className="createLabel createTime">
<label> Time </label>
<span className="createTimeHolder">
<input
className="startTime"
type="text"
name="startTime"
value={ this.state.create.startTime }
onChange={ this.createHandler }
placeholder='Start time'
autoComplete="off"
/>
<input
className="endTime"
name="endTime"
value={ this.state.create.endTime }
onChange={ this.createHandler }
placeholder='End time'
autoComplete="off"
/>
</span>
</span>
<span className="createLabel createDate">
<label> Date </label>
<span className="createDateHolder">
<input
ref={this.daySelect}
type="text"
className=""
name="date"
value={ this.state.create.date }
onChange={ this.createHandler }
placeholder='DD'
autoComplete='off'
/>
<p>/</p>
<input
ref={this.monthSelect}
type="text"
className=""
name="month"
value={ this.state.create.month }
onChange={ this.createHandler }
placeholder='MM'
autoComplete='off'
/>
<p>/</p>
<input
ref={this.yearSelect}
type="text"
className=""
name="year"
value={ this.state.create.year }
onChange={ this.createHandler }
placeholder='YYYY'
autoComplete='off'
/>
<span className="iconHolder" onClick={ this.dateSelector }>
<i className="calendar alternate outline icon"></i>
{ this.state.miniCalendar }
</span>
</span>
</span>
</form>
</div>
</div>
</div>
);
this.setState({
popup: elements
});
setTimeout(() => {
this.closeX.current.addEventListener('click', this.closePopup);
}, 0);
document.body.addEventListener('click', this.closePopup);
};
selected = (date, i, whatMonth) => {
let newDate = new Date(date);
const { create } = this.state;
newDate.setDate(1);
newDate.setHours(0,0,0,0);
let toSet = {
d: null,
m: null,
y: null
}
if(whatMonth === 'prev') {
const prevMonth = new Date(newDate.getFullYear(), newDate.getMonth(), 0);
prevMonth.setDate(prevMonth.getDate() - i);
toSet = {
d: prevMonth.getDate().toString(),
m: (prevMonth.getMonth() + 1).toString(),
y: prevMonth.getFullYear().toString()
}
}else if(whatMonth === 'current') {
newDate.setDate(i);
toSet = {
d: newDate.getDate().toString(),
m: (newDate.getMonth() + 1).toString(),
y: newDate.getFullYear().toString()
}
}else if(whatMonth === 'next') {
newDate.setMonth(newDate.getMonth() + 1);
newDate.setDate(i);
toSet = {
d: newDate.getDate().toString(),
m: (newDate.getMonth() + 1).toString(),
y: newDate.getFullYear().toString()
}
}
const day = this.daySelect.current;
const month = this.monthSelect.current;
const year = this.yearSelect.current;
var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
var ev = new Event('input', { bubbles: true});
nativeInputValueSetter.call(day, toSet.d);
day.dispatchEvent(ev);
nativeInputValueSetter.call(month, toSet.m);
month.dispatchEvent(ev);
nativeInputValueSetter.call(year, toSet.y);
year.dispatchEvent(ev);
}
dateSelector = event => {
//When state is updated in this function the function this.createEvent doesnt update
let elem = {
miniCalendar: (
<>
<div ref={ this.dateSelectorHolder } className="dateSelector">
<DateSelector selected={ this.selected } />
</div>
</>
)
};
this.setState(elem);
setTimeout(() => {
document.body.addEventListener('click', this.closePopup);
}, 0);
};
// -- End of popup related code --
createHandler = event => {
const { create } = this.state;
const name = event.target.name;
const value = event.target.value;
this.setState({
create: {
...create,
[name]: value
}
});
};
render() {
return (
<div className={ this.state.className }>
<CalendarHeader createEvent={ this.createEvent } type={this.state.displayType.type} displayTypeHandler={ this.displayTypeHandler } resetDate={ this.resetDate } leftButton={ this.leftButton } rightButton={ this.rightButton } selectedTime={this.state.today}/>
{ this.displayType() }
{ this.state.popup }
</div>
);
};
};
export default Calendar;
我从文件中删除了一堆与我的问题无关的代码