已经更新状态后再次更新状态

时间:2020-04-23 04:43:57

标签: reactjs

我正在构建一个日历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的解决方案,但这当然会创建一个无限循环。

1 个答案:

答案 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]);