You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DevExpress React Scheduler类组件转函数组件后表单无法编辑问题求助

问题根因

你改写Hooks时混淆了类组件合并式state和Hooks独立状态的用法,导致EditingState拿到的状态格式完全错误,所以表单无法交互,具体修改点如下:

  1. 三个状态更新函数错误地给值额外套了一层对象,类组件setState({ addedAppointment })是因为类组件的state是对象,而Hooks里单个状态直接存值即可,不需要包裹
  2. commitChanges中setData的回调写法错误,类组件的状态回调返回的是需要合并的state对象,而Hooks的setData直接返回新的数组值即可
  3. 子组件初始data仅在第一次创建时赋值父组件传入的shifts,父组件异步拉取到shifts更新后子组件不会同步,需要加useEffect监听同步
  4. id生成逻辑漏写了.length属性判断

修正后的DataSheet完整代码

import React, { useState, useEffect } from 'react';
import Paper from '@material-ui/core/Paper';
import { ViewState, EditingState } from '@devexpress/dx-react-scheduler';
import {
  Scheduler,
  Appointments,
  AppointmentForm,
  AppointmentTooltip,
  WeekView,
} from '@devexpress/dx-react-scheduler-material-ui';
  
const DataSheet = ( { addShift, shifts, deleteShift } ) => {
    const [data, setData] = useState(shifts)
    const [currentDate, setCurrentDate] = useState('2018-06-27')
    const [addedAppointment, setAddedAppointment] = useState({})
    const [appointmentChanges, setAppointmentChanges] = useState({})
    const [editingAppointment, setEditingAppointment] = useState(undefined)

    // 同步父组件传入的排班数据
    useEffect(() => {
      setData(shifts)
    }, [shifts])
  
    const changeAddedAppointment = (addedAppointment) => {
        // 去掉多余的对象包裹
        setAddedAppointment(addedAppointment);
    }

    const changeAppointmentChanges = (appointmentChanges) => {
        // 去掉多余的对象包裹
        setAppointmentChanges(appointmentChanges);
    }

    const changeEditingAppointment = (editingAppointment) => {
        // 去掉多余的对象包裹
        setEditingAppointment(editingAppointment);
    }

    const commitChanges = ({ added, changed, deleted }) => {
      setData ((prevData) => {
        let newData = [...prevData];
        if (added) {
          const startingAddedId = newData.length > 0 ? newData[newData.length - 1].id + 1 : 0;  
          newData = [...newData, { id: startingAddedId, ...added }];
          addShift(added);
        }
        // 直接返回新数组即可,不需要包裹对象
        return newData;
      });
    }

    return (
      <Paper>
        <Scheduler
          data={data}
          height={660}
        >
          <ViewState
            currentDate={currentDate}
            onCurrentDateChange={setCurrentDate}
          />
          <EditingState
            onCommitChanges={commitChanges}
            addedAppointment={addedAppointment}
            onAddedAppointmentChange={changeAddedAppointment}
            appointmentChanges={appointmentChanges}
            onAppointmentChangesChange={changeAppointmentChanges}
            editingAppointment={editingAppointment}
            onEditingAppointmentChange={changeEditingAppointment}
          />
          <WeekView
            startDayHour={9}
            endDayHour={17}
          />
          <Appointments />
          <AppointmentTooltip
            showOpenButton
            showDeleteButton
          />
          <AppointmentForm />
        </Scheduler>
      </Paper>
    );
}

export default DataSheet

可选优化

父组件已经维护了完整的shifts数组,你也可以直接把Scheduler的data属性设为shifts,删掉子组件内部的data状态和对应的同步useEffect,减少重复状态维护。


内容的提问来源于stack exchange,提问作者Kahalon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 21:39:04