首页 > 解决方案 > 如何通过使用 reducer 和处理事件来更新事件数组中的事件?

问题描述

我正在使用fullcalendar来显示我的 React 应用程序中的所有事件。

理想情况下,prevnext事件处理程序应该重新呈现事件。

这是我的代码。

calender_slice.js

const slice = createSlice({
  name: 'calendar',
  initialState,
  reducers: {
    getEvents(state, action) {
      const { timecards } = action.payload;

      const timecard_events = timecards.map(timecard => {
        return {
          title: `${timecard.first_name} ${timecard.last_name}(${timecard.role})`,
          start: timecard.clock_in,
          end: timecard.clock_out,
          color: '#'+Math.floor(Math.random()*16777215).toString(16)
        }
      })

      state.events = [...timecard_events];

      state.isLoading = false;
    },
    ...
export const getEvents = (
  start_date = moment().startOf('month').toString(),
  end_date = moment().toString()
) => async (dispatch) => {
  dispatch(slice.actions.setLoading(true));

    const res = await axios.post(`${backend}/timecards`, {
      start_date,
      end_date
    })

    dispatch(slice.actions.getEvents({timecards: res.data.timecards}));
};

calendar_view.js

const CalendarView = () => {
    const calendarRef = useRef(null);
    const dispatch = useDispatch();
    const { events, isModalOpen, selectedRange, isLoading } = useSelector((state) => state.calendar);

    const handleDatePrev = async () => {
      const calendarEl = calendarRef.current;

      if (calendarEl) {
        const start_date = moment(calendarEl.props.defaultDate).subtract(1, 'month').startOf('month').format();
        const end_date = moment(calendarEl.props.defaultDate).subtract(1, 'month').endOf('month').format();
        const calendarApi = calendarEl.getApi();

        try {
          await dispatch(getEvents(true, start_date, end_date));
        } catch (err) {
          console.error(err);
        }

        calendarApi.prev();
        setDate(calendarApi.getDate());
      }
    };

  return (<Container maxWidth={false}>
          <Header onAddClick={handleAddClick} />
          <Toolbar
            date={date}
            onDateNext={handleDateNext}
            onDatePrev={handleDatePrev}
            onDateToday={handleDateToday}
            onViewChange={handleViewChange}
            view={view}
          />
          <Paper className={classes.calendar}>
            <FullCalendar
              allDayMaintainDuration
              defaultDate={date}
              defaultView={view}
              eventResizableFromStart
              eventResize={handleEventResize}
              events={events}
              header={false}
              height={800}
              ref={calendarRef}
              rerenderDelay={10}
              weekends
              plugins={[
                dayGridPlugin,
                timeGridPlugin,
                interactionPlugin,
                listPlugin,
                timelinePlugin
              ]}
            />
          </Paper>
        </Container>
  )
}

此代码工作正常并且每次都正确调度事件,但fullcalendar不显示更新的事件数组。

我想知道作为当前日期我应该得到什么值。

标签: javascriptreactjsreduxfullcalendarslice

解决方案


可能是由于状态的突变而发生的。在 reducer 中,您应该返回一个新状态(不改变旧状态)。请参阅:https ://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers#rules-of-reducers 更改getEvents为:

getEvents(state, action) {
  const { timecards } = action.payload;

  const timecard_events = timecards.map(timecard => {
    return {
      title: `${timecard.first_name} ${timecard.last_name}(${timecard.role})`,
      start: timecard.clock_in,
      end: timecard.clock_out,
      color: '#'+Math.floor(Math.random()*16777215).toString(16)
    }
  })

  return {
    ...state,
    events: [...timecard_events],
    isLoading: false,
  }
},

推荐阅读