简体   繁体   English

如何在React上使用undo操作设置初始状态?

[英]How to set initial state with undo action on React?

I have a react-big-calendar with drag and drop, I want when I move an event to another position, a snackbar appeared which having the undo action like that : 我有一个带有拖放功能的react-big-calendar,我想将事件移动到另一个位置时,出现一个小吃栏,它具有这样的undo操作:

在此处输入图片说明

I want when I click on the undo action, the event set the initial state (the initial position) 我想要当我单击撤消操作时,事件设置初始状态(初始位置)

My code is : 我的代码是:

 moveEvent = ({event, start, end, isAllDay: droppedOnAllDaySlot}) => {
      const { events } = this.state;
      const idx = events.indexOf(event);
      let allDay = event.allDay ;
      if(!event.allDay && droppedOnAllDaySlot)
      {allDay = true;}
      else if (event.allDay && !droppedOnAllDaySlot)
      { allDay = false;}
      const updatedEvent = { ...event, start, end, allDay }
      const nextEvents = [...events]
      nextEvents.splice(idx, 1, updatedEvent)
      this.setState({
        events : nextEvents,
        dragAndDrop : true,
        open : true
      })
  }
  handleClose = () => {
      this.setState({ open: false });
  };
  handleClick = () => {
      this.setState({ open: true });
  };
  handleUndo = () => {
      this.setState({
        dragAndDrop : !this.state.dragAndDrop,
        events: this.state.events
      })
 }
  render() {
    return (
       <div>
          <DragAndDropCalendar
            selectable
            localizer={localizer}
            events={this.state.events} 
            views={['month','week','day']}
            //defaultDate={new Date(2019, 2, 19)}
            defaultView="week"
            culture = 'fr'
            timeslots={1}
            step={15}
            style={{ height: "100vh" }}
            onEventDrop={this.moveEvent}
            min={new Date(2017, 10, 0, 7, 0, 0)}
            max={new Date(2017, 10, 0, 21, 0, 0)} 
            resizable  
            onEventResize={this.resizeEvent}
            onSelectSlot={this.newEvent}
            onSelectEvent={this.handleClickOpen}
          />
        <Snackbar
          anchorOrigin={{
            vertical: 'bottom',
            horizontal: 'center',
          }}
          open={this.state.open}
          autoHideDuration={6000}
          onClose={this.handleClose}
          ContentProps={{
            'aria-describedby': 'message-id',
          }}
          message={<span id="message-id">Evénement enregistré</span>}
          action={[
              <Button key="undo" color="secondary" size="small" onClick={this.handleUndo}>
                Annuler
              </Button>,
              <IconButton
                key="close"
                aria-label="Close"
                color="inherit"
                onClick={this.handleClose}
              >
                <CloseIcon />
              </IconButton>,
            ]}
        />

My full code : https://codesandbox.io/s/mq42x1j90x 我的完整代码: https : //codesandbox.io/s/mq42x1j90x

When I run my code and I click on the undo action, it doesn't work, and my event doesn't set the initial position. 当我运行代码并单击“撤消”操作时,它不起作用,并且我的事件未设置初始位置。

How can I fix that ? 我该如何解决?

I suggest to store previous events in separate field inside this.state(for instance, this.state.previousEvents) , and at undo() action set current events to previous events. 我建议将先前事件存储在this.state(例如this.state.previousEvents)内的单独字段中,并在undo()动作中将当前事件设置为先前事件。 Also, when user closes snackbar or do some other action which changes events and can't be reverted, don't forget to update previousEvents as current events value. 另外,当用户关闭快餐栏或执行其他一些更改事件且无法还原的操作时,请不要忘记将previousEvents更新为当前事件值。

Also instead of using this.state in this.setState 也代替this.setState使用this.state

this.setState({
        dragAndDrop : !this.state.dragAndDrop,
        events: this.state.events
      })

you should use previousState : 您应该使用previousState

this.setState((prevState) => ({
        dragAndDrop : !prevState.dragAndDrop,
        events: prevState.events
      }))

So the full version is 所以完整版是

class Calendar extends Component {
  state  = {
    events: [],
    prevEvents: []
  };

  handleUndo = () => {
    this.setState((prevState) => ({
      events: prevState.prevEvents
    }))
  }

  handleCloseSnackbar = () => {
    this.setState((prevState) => ({
      prevEvents: prevState.events
    }))
  }

  ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM