这个问题很简单,但是我无法弄清楚这个问题;我需要渲染一个日期选择模块,该模块显示first_possible_date
和接下来的6天,以及能够来回导航直到达到last_possible_date
的功能。 last_possible_date
之后的每个日期都需要禁用。如果导航位置早于first_possible_date
,则不能向后导航;如果导航位置超过last_possible_date
,则不能向后导航。
我正在使用的数据是具有星期几作为其子对象的对象,如下所示:
{
"1": { "name": "Monday", "categories": [5] },
"1": { "name": "Tuesday", "categories": [5] },
"1": { "name": "Wednesday", "categories": [5] },
"1": { "name": "Thursday", "categories": [5] },
"1": { "name": "Friday", "categories": [5] }
}
此数据与first_possible_date
和last_possible_date
一起通过道具传递到我的组件中。在componentDidMount函数中,我将数据设置为状态,如下所示:
this.setState({
data: this.props.data
}, () => {
this.getFormattedDates(this.props.firstpossible);
});
在getFormattedDates
函数中,我使用其教程应用程序中React提到的不变性,将数据设置在局部变量中,将数据保存在this.state.data
中,如下所示:
let dates = Object.assign({}. this.state.data);
category变量包含一些我需要在UI中呈现(或不呈现)某些组件的信息。但是如您所见,该数组尚未包含所有日期,因此我需要添加它们。为此,我有一系列的日期,并检查星期几是否在我的数据数组中,就像这样:
// //Add saturday and sunday to the array, as well as add additional data
for (var i = 0; i < daysoftheweek.length; i++) {
let datefound = false;
let dayoftheweekindex = i * 1 + 1;
let j = (Object.keys(dates).length === 7) ? 0 : 1;
let limit = (Object.keys(dates).length === 7) ? 6 : 5;
for (j; j <= limit; j++) {
if (daysoftheweek[i].toLowerCase() === dates[j].name.toLowerCase()) {
dates[j]['dayoftheweek'] = dayoftheweekindex;
dates[j]['name'] = dates[j]['name'].toLowerCase();
datefound = true;
}
}
if (!datefound) {
let newindex = dayoftheweekindex - 1;
dayoftheweekindex = (dayoftheweekindex === 7) ? 0 : dayoftheweekindex;
dates[dayoftheweekindex] = {
name: daysoftheweek[newindex],
categories: [],
dayoftheweek: dayoftheweekindex
};
}
}
完成此操作后,我想移动数组,以使first_possible_date
是数组中的第一个数组,以便更轻松地(重新)呈现日期选择,如下所示:
// Shift the array, so the first element is the day after the first possible transport date.
let shiftedDates = [];
let firstPossible = startdate.getDay();
for (var i = 0; i < Object.keys(dates).length; i++) {
let date = dates[i];
if (date.dayoftheweek < firstPossible) {
shiftedDates.splice(shiftedDates.length, 0, dates[i]);
} else {
shiftedDates.splice(i - firstPossible, 0, dates[i]);
}
}
最后,我添加了一些额外的数据,如果日期超过了categories
,则清空last_possible_date
变量(如果categorys数组为空,则禁用按钮),并以4 / 3个要渲染的对象,如下所示:
//Finally, add some more data to every shifted element, so it can be used for displaying.
for (let i in shiftedDates) {
let incrementedDate = Helper.addDaysToDate(startdate, i * 1);
shiftedDates[i]['dayofthemonth'] = incrementedDate.getDate();
shiftedDates[i]['monthIndex'] = incrementedDate.getMonth();
shiftedDates[i]['month'] = months[incrementedDate.getMonth()];
shiftedDates[i]['year'] = incrementedDate.getFullYear();
let lastPossibleDate = this.props.lastpossible;
if (shiftedDates[i].monthIndex > lastPossibleDate.getMonth() || (shiftedDates[i].monthIndex === lastPossibleDate.getMonth() && shiftedDates[i].dayofthemonth > lastPossibleDate.getDate())) {
shiftedDates[i].categories = [];
}
if (true) {}
}
let formattedDates = {
0: [
shiftedDates[0],
shiftedDates[1],
shiftedDates[2],
shiftedDates[3],
],
1: [
shiftedDates[4],
shiftedDates[5],
shiftedDates[6],
]
};
this.setState({otherdates: formattedDates});
来回导航,我会在startdate
上添加或删除几天,就像这样:
let startdate = this.state.startdate;
if (moveahead) {
let startDateBuffer = Helper.addDaysToDate(startdate, 7);
if (startDateBuffer < this.props.lastpossible) {
this.hideAll();
startdate = Helper.addDaysToDate(startdate, 7);
}
} else {
if (this.props.firstpossible < startdate) {
this.hideAll();
startdate = Helper.addDaysToDate(startdate, -7);
}
}
this.getFormattedDates(startdate);
即使代码可能很凌乱,也都可以正常工作,但是我需要解决一个问题。
您会看到,即使我从this.state.data
中的数据创建了一个变量,但是当我修改本地创建的变量let dates
时,它仍然是突变的。更奇怪的是,第一次记录this.state.data
会导致数据已被修改。在创建let dates
变量和向数组添加星期六和星期日的循环之间,我放置了一个日志console.log(this.state.data);
,即使在第一次迭代时,它也显示了星期六和星期日已经是添加,而下面添加它们的代码尚未执行(在日志之后执行)。生成的JSON如下所示:
{
"0": { "name": "sunday", "categories": [0], "dayoftheweek": 7, "dayofthemonth": 9, "monthIndex": 8, "month": "september", "year": 2018 },
"1": { "name": "monday", "categories": [5], "dayoftheweek": 1, "dayofthemonth": 10, "monthIndex": 8, "month": "september", "year": 2018 },
"2": { "name": "tuesday", "categories": [5], "dayoftheweek": 2, "dayofthemonth": 4, "monthIndex": 8, "month": "september", "year": 2018 },
"3": { "name": "wednesday", "categories": [5], "dayoftheweek": 3, "dayofthemonth": 5, "monthIndex": 8, "month": "september", "year": 2018 },
"4": { "name": "thursday", "categories": [5], "dayoftheweek": 4, "dayofthemonth": 6, "monthIndex": 8, "month": "september", "year": 2018 },
"5": { "name": "friday", "categories": [5], "dayoftheweek": 5, "dayofthemonth": 7, "monthIndex": 8, "month": "september", "year": 2018 },
"6": { "name": "saturday", "categories": [0], "dayoftheweek": 6, "dayofthemonth": 8, "monthIndex": 8, "month": "september", "year": 2018 }
}
如果当前迭代日期超出categories
,则执行修改last_possible_date
变量的代码时,将按预期方式正确清空类别并禁用UI中的按钮。但是,当您再次导航时,它们仍然被禁用,因为类别数组保持为空。再次记录this.state.data
会发现数据已更改,在某些日子中空categories
数组为空。
所以,tl; dr ...