我尝试构建日历,并可能添加当天的注释。我的组件的结构如下: 应用程序组件是通用组件,可呈现主要的Build组件。构建组件使用CellBuild组件构建日历的日期和一个DayEventBuilder,该事件将在单击单元格时显示。
我尝试通过单击来更改CellBuild组件中Builder的“ day”状态,然后更改DayEventBuilder的状态以显示实际日期。我在更改DayEventBuilder的状态时遇到问题,因为它无法通过Builder的组件获取状态。
只有两次单击后,CellBuild中的“天”状态才会更改。 DayEventBuilder组件没有从Builder获得任何状态。
应用组件
import 'bootstrap/dist/css/bootstrap.css';
import React from 'react';
import './App.css';
import Builder from './Components/Builder.js';
let helpDate = new Date();
class App extends React.Component {
render() {
return (
<div className="App">
<Builder helpDate={helpDate}/>
</div>
);
}
}
export default App;
构建器组件
import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import CellBuild from './CellBuild.js';
import DayEventBuilder from './DayEventBuilder.js';
import $ from 'jquery';
let currentDate= new Date();
let months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
//let month = currentDate.getMonth(); //current month
//let year = currentDate.getFullYear(); //current year
//Builder calendar body
class Builder extends React.Component {
constructor(props) {
super(props);
this.state = {
dataState: this.props.helpDate, //set date to build and display
};
}
//help function to control date parameters in cell which is clicked
clickCell=x=>{
this.setState({day:x});
};
createTable =(data)=>{
let helpDate = new Date(data.getFullYear(), data.getMonth(), data.getDate()); //help date for drawing
let helpOther = new Date(data.getFullYear(), data.getMonth(), data.getDate()); //help date for build previous month days
helpDate.setDate(1);
helpOther.setDate(1);
let table=[]; //create table container
let rows=[]; //create rows container
//outer loop for rows creating (filling rows container)
for(let i=0;i<6;i++){
let cells=[]; //create empty cells container
//inner loop for cells creating in row (filling cells container)
for (let j=0;j<7;j++){
//loop for draw previous month days and padding current 1st days relative days of week
if(i===0&&j<helpDate.getDay()-1){
helpOther.setDate(-helpDate.getDay()+2+j);
cells.push(<CellBuild date={helpOther.getDate()} month={helpOther.getMonth()} isNowDate="numbers otherMonth"/>);
}
//continue drawing calendar
else{
//if current month
if(helpDate.getMonth()===data.getMonth()){
//checking for today
if(helpDate.getDate()===currentDate.getDate()&&helpDate.getMonth()===currentDate.getMonth()&&helpDate.getFullYear()===currentDate.getFullYear()){
cells.push(<CellBuild clickCell={this.clickCell} date={helpDate.getDate()} month={helpDate.getMonth()} isNowDate="numbers nowDate"/>); //join cell to cells container
}
else{
cells.push(<CellBuild clickCell={this.clickCell} date={helpDate.getDate()} month={helpDate.getMonth()} isNowDate="numbers" />); //join cell to cells container
}
}
//next month days
else{
cells.push(<CellBuild clickCell={this.clickCell} date={helpDate.getDate()} month={helpDate.getMonth()} isNowDate="numbers otherMonth" />); //join cell to cells container
}
helpDate.setDate(helpDate.getDate()+1);
}
}
rows.push(<tr>{cells}</tr>); //join filled cells container to rows container (join a row)
}
table.push(<table className="main col-lg-12 col-md-12 col-sm-12 col-xs-12"><thead><tr><th colSpan={2}><button className="decrease" onClick=
{() =>
{
data.setMonth(data.getMonth()-1);
this.setState({dataState:data});
}}>←</button><div className="head">{months[data.getMonth()]}</div><div className="head">{data.getFullYear()}</div><button className="increase" onClick=
{() =>
{
data.setMonth(data.getMonth()+1);
this.setState({dataState:data});
}}>→</button></th></tr></thead><tbody>{rows}</tbody></table>); //join filled rows container to table and make header
return table;
};
render() {
return (
<div className="container">
<div className="calendar">{this.createTable(this.state.dataState)}</div>
<DayEventBuilder day={this.state.day}/>
</div>
)
}
}
export default Builder;
CellBuild
import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import $ from 'jquery';
//holidays list
let holidays = [
{id:0,
name:"New year",
date:'01.01'},
{id:1,
name:"Christmas",
date:'01.07'},
{id:2,
name:"Men's day",
date:'02.23'},
{id:3,
name:"Women's day",
date:'03.08'},
{id:4,
name:"Labor day",
date:'05.01'},
{id:5,
name:"Victory Day",
date:'05.09'},
{id:6,
name:"Independence day",
date:'07.03'},
{id:7,
name:"November revolution day",
date:'11.07'}];
class CellBuild extends React.Component {
constructor() {
super();
this.state = {
holidaysState: holidays,
};
}
render(){
//do default cell value if not holiday
let cell=<td tabIndex="0" onClick={() => {
console.log(this.props.date);
this.setState({day:this.props.date}); //set day in state to render actual DayEventBuilderComponent
console.log(this.state.day);
//this.setState({month:this.props.month}); //set day in state to render actual DayEventBuilderComponent
this.props.clickCell(this.state.day);
$(function () {
$('table.main').css('opacity','.5');
$('table.dayEvents').css('display','table');
})
}
}><div tabIndex="0" className={this.props.isNowDate}><p>{this.props.date}</p></div></td>;
//check for holiday day
this.state.holidaysState.map(function(holiday){
//create temporary date object from date parameter of holiday
let tempDate = new Date(holiday.date);
//if current day is holiday change a cell value for this day in calendar
if(tempDate.getMonth()===this.props.month&&tempDate.getDate()===this.props.date ){
cell=<td tabIndex="0" onClick={() => {
$(function () {
$('table.main').css('opacity','.5');
$('table.dayEvents').css('display','table');
});
}
} className="holiday"><div tabIndex="0" className={this.props.isNowDate}><p>{this.props.date}</p></div><p className="holiday">{holiday.name}</p></td>;
}
},this); //give CellBuilder as the context of map-function
return cell;
}
}
export default CellBuild;
DayEventBuilder
import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import $ from 'jquery';
let events = [
{id:0,
date:"2019.01.20",
name:"Event 1 for this day",
time1:"15:00",
time2:"19:00"
},
];
class DayEventBuilder extends React.Component {
constructor(props) {
super(props);
this.state = {
day:this.props.day, //take actual day and month of the clicked cell from CellBuild
month:this.props.month,
};
}
render(){
let table=[]; //create table container
let rows=[]; //create rows container
let skip=0; //skip <td> adding if needed
//build table
for (let i=0;i<25;i++){
let cells=[]; //create empty cells container
cells.push(<td>{i+':00'}</td>);
if((i+':00')===events[0].time1){
let rowspan = events[0].time2.substring(0, 2)-events[0].time1.substring(0, 2); //calculate how long will the event be
cells.push(<td rowSpan={rowspan} className="setEvent">{events[0].name}</td>);
skip=rowspan; //set skip counter
}
if(skip<=0){ //if we finished skip <td> adding while event was
cells.push(<td onClick={() => {
$(function () {
$('table.main').css('opacity','.3');
$('table.dayEvents').css('opacity','.5');
$('.form').css('display', 'block');
})
}}/>);
}
--skip;
rows.push(<tr>{cells}</tr>);
}
//create table and create exit button from events list
//console.log('DayEventBuilder state.day ='+this.state.day);
table.push(<table className="dayEvents col-lg-6 col-md-8 col-sm-10 col-xs-10"><thead><tr><th>{this.state.day}</th><th><button onClick={() => {
$(function () {
$('table.main').css('opacity','1');
$('table.dayEvents').css('display','none');
})
}
}>×</button></th></tr></thead><tbody>{rows}</tbody></table>);
return (<div>
<div>{table}</div>
<div className="form col-lg-6 col-md-6 col-sm-8 col-xs-8">
<button onClick={() => {
$(function () {
$('table').css('display', 'table');
$('.form').css('display', 'none');
$('table.dayEvents').css('opacity','1');
$('table.main').css('opacity','.5');
})
}}>←</button>
<form>
<fieldset>
<select className="form-control">
<option value="one">One</option>
<option value="two">Two</option>
<option value="three">Three</option>
<option value="four">Four</option>
<option value="five">Five</option>
</select>
<legend>Add the event</legend>
<p>Description <input name="login"/></p>
<p><input type="submit" value="Add"/></p>
</fieldset>
</form>
</div>
</div>);
}
}
export default DayEventBuilder;
答案 0 :(得分:2)
在CellBuild
点击处理程序中可能是一个问题。
此代码无法正常运行,因为setState是异步的。
() => {
this.setState({day:this.props.date});
this.props.clickCell(this.state.day);
}
尝试将其更改为此。
() => {
this.setState({day:this.props.date});
this.props.clickCell(this.props.date);
}
将jquery
与react
一起使用也是一种不好的做法。
答案 1 :(得分:0)
1。。从 BuilderComponent 和 DayEventBuilder 的构造函数中的props
获取值的方式是错误的,请更改< strong> this.props 到 props 。
更改
constructor(props) {
super(props);
this.state = {
dataState: this.props.helpDate, //this.props is not required here
};
}
收件人
constructor(props) {
super(props);
this.state = {
dataState: props.helpDate, //props.helpDate is enough
};
}
2。。BuilderComponent中的 SetSate 设置了错误的状态变量。
更改:
clickCell=x=>{
this.setState({day:x});
};
收件人:
clickCell=x=>{
this.setState({dataState:x});
};