我正在构建一个日历React.js应用程序。
当我单击日历中的单元格时,它将创建一个新事件,并将其添加到EventList状态。
EventList = [{},{},{},{}];
创建新事件时,需要更新此数组中所有其他事件的width属性,以使其可见。
const createEvent = (e) => {
let startTime = e.target.id;
let endTime = day[day.indexOf(e.target.id) + 1];
let newEvent = {
id: uuid(),
startTime,
endTime,
height: columnHeight,
width: 90,
seq: [startTime, endTime],
};
let updEvents = [...events, newEvent];
setevents(updEvents);
console.log(newEvent.seq);
getCollisions()
};
const getCollisions = () => {
let zIndex = 0;
setzIndexState(0);
for (let slot of day) {
let eventsInThisSlot = events.filter((event) => (
event.startTime === slot
));
if (eventsInThisSlot.length > 0) {
console.log('eventsInThisSlot', eventsInThisSlot)
let sorted = sortArrays(eventsInThisSlot);
let width = 100;
let updEvents = [...events];
let index = -1;
for (let event of sorted) {
width = findParentWidth(slot);
index = updEvents.findIndex(obj => obj.id === event.id);
updEvents[index].width = width * (1 - (sorted.indexOf(event) / sorted.length));
updEvents[index].zIndex = zIndex;
console.log('zindex', updEvents[index].zIndex)
zIndex++;
setevents([
...updEvents
]);
};
}
}
setzIndexState(zIndex);
}
我的getCollisions函数需要遍历整个列表,并在计算出正确的比例后更新宽度。
第一个事件可以添加,但是当我尝试添加第二个事件时,它没有添加。
我认为在确保已将元素添加到状态后,必须运行第二个功能。
我尝试过考虑使用useEffect的解决方案,但这当然会创建一个无限循环。
答案 0 :(得分:1)
const createEvent = (e) => {
let startTime = e.target.id;
let endTime = day[day.indexOf(e.target.id) + 1];
let newEvent = {
id: uuid(),
startTime,
endTime,
height: columnHeight,
width: 90,
seq: [startTime, endTime],
};
let updEvents = [...events, newEvent];
// setevents(updEvents); // <-- update update your state after getColiisions done
console.log(newEvent.seq);
getCollisions(updEvents); // <-- pass all the new events
};
然后
const getCollisions = (allEvents) => { // <--- get the events
let zIndex = 0;
setzIndexState(0);
let updEvents = [...events]; // <--- create new updEvents
for (let slot of day) {
let eventsInThisSlot = allEvents.filter((event) => ( // <-- use the events arguments.
event.startTime === slot
));
if (eventsInThisSlot.length > 0) {
console.log('eventsInThisSlot', eventsInThisSlot)
let sorted = sortArrays(eventsInThisSlot);
let width = 100;
let index = -1;
for (let event of sorted) {
width = findParentWidth(slot);
index = updEvents.findIndex(obj => obj.id === event.id);
updEvents[index].width = width * (1 - (sorted.indexOf(event) / sorted.length));
updEvents[index].zIndex = zIndex;
console.log('zindex', updEvents[index].zIndex)
zIndex++;
};
}
}
setevents([ // <--- set the event at once
...updEvents
]);
setzIndexState(zIndex);
}
如果您需要使用useEffect挂钩,我认为最好将事件状态设置为:
const [event, setevent] = useState({
data: [],
version: 0
});
然后像这样在createEvent方法中将版本增量设置为1
const createEvent = (e) => {
...
let updEvents = [...events, newEvent];
setevents({
data: updEvents,
version: events.version+1 //<--- increment version just in createEvent method
});
console.log(newEvent.seq);
getCollisions()
};
然后像这样钩住useEffect ...
useEffect(() => {
...
}, [events.version]);