我试图在日历上添加一天的笔记。我的组件的结构如下: App组件是常见的组件,它呈现主构建组件。Build组件使用CellBuild组件来构建日历的天数和一个DayEventBuilder,它将显示何时单击单元格。
我尝试通过单击来更改CellBuild组件中的Builder的“日期”状态,然后更改DayEventBuilder的状态以显示实际的日期。更改DayEventBuilder的状态有问题,因为它没有通过Builder的组件获得状态。
CellBuild中的"day“状态只在单击两次之后才会发生变化。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;发布于 2019-01-16 20:20:02
这可能是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结合使用也是一种糟糕的做法。
发布于 2019-01-14 10:27:51
从BuilderComponent和DayEventBuilder的构造函数中从props获取值的方式是错误的,请将this.props更改为props。
Change
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. SetSate in BuilderComponent在状态中设置了错误的变量。
变更:
clickCell=x=>{
this.setState({day:x});
};To:
clickCell=x=>{
this.setState({dataState:x});
};https://stackoverflow.com/questions/54179595
复制相似问题