React react-sortable-hoc cancel reordering(Undo order changes)

470 views Asked by At

I'm using react-sortable-hoc to reorder table rows with Save and Cancel buttons. However, I can't find any information or example about reverting back to original order when the Cancel button is clicked after re-ordered rows.

Can't find any info or example on the official documentation or anywhere else. It seems weird to me that there's no cancel function built in or am I missing something?

Edit: Example code

1

There are 1 answers

2
Drew Reese On BEST ANSWER

If you want to undo order changes then you can maintain an undo stack. Each time an order change is complete, stash a copy of the previous data state. When the undo button is clicked you pop from the undo stack back into the data state.

  1. Add an undoStack to state.

    state = {
      data: range(1, 5).map((el) => ({
        name: `tester-${el}`,
        age: el,
        class: `Class-${el}`
      })),
      undoStack: [],
    };
    
  2. Cache the previous data state in the undo stack. Here I'm using slice to keep only the last 10 revisions, but this can be tuned to fit your needs.

    _handleSort = ({ oldIndex, newIndex }) => {
      this.setState((prevState) => ({
        data: arrayMove(prevState.data, oldIndex, newIndex),
        undoStack: [...prevState.undoStack, prevState.data].slice(-10),
      }));
    };
    
  3. Handle undoing order changes and attach the undo handler to the button's onClick event handler.

    undo = () => {
      this.setState(prevState => {
        if (prevState.undoStack.length) {
          return {
            data: prevState.undoStack.pop(),
            undoStack: prevState.undoStack,
          };
        } else {
          return prevState;
        }
      })
    };
    
    ...
    
    <button type="button" onClick={this.undo}>
      Undo reorder
    </button>
    

Demo

Edit react-react-sortable-hoc-cancel-reorderingundo-order-changes

If you don't care about intermediate revisions and simply want to reset to the original order then just capture a cache of the original order and reset data.

const data = range(1, 5).map((el) => ({
  name: `tester-${el}`,
  age: el,
  class: `Class-${el}`
}));

class App extends React.Component {
  state = {
    data,
    originalData: data, // <-- store cache of original data
    undoStack: []
  };

  ...

  <button
    type="button"
    onClick={() => {
      this.setState({
        data: this.state.originalData // <-- restore from cache
      });
    }}
  >
    Reset
  </button>

Both are implemented in the linked codesandbox.