SortableJS / react-sortablejs

React bindings for SortableJS
http://sortablejs.github.io/react-sortablejs/
MIT License
2.07k stars 211 forks source link

[bug] Sortable.get(event.target).sort not working as expected #257

Open FFdhorkin opened 2 years ago

FFdhorkin commented 2 years ago

Describe the bug I have a series of rows, each of which has a label that shows its current index.

Without an onChange handler, the controls reorder properly, but the index label is not updating.

With my onChange handler, nothing happens visually when I drag item # 3 over # 2 (though I can see a console.log showing the correct oldIndex and newIndex). When I drag item # 3 over item # 1, suddenly the index labels /controls fluctuate rapidly. It looks like item # 1 and # 3 are swapping positions repeatedly.

I originally tried to use setState in the onChange handler, but that seemed to lead to duplicate controls for some reason. (There were also errors about q.parentNode is null when I tried setState)

To Reproduce Steps to reproduce the behavior:

  1. In child object, have an index in props that is used for displaying row #
  2. add onChange handler to container:

    onChange={(event, sortable) => {
    event.stopPropagation();
    const { oldIndex, newIndex } = event;
    const order = sortable!.toArray();
    
    console.log(`${oldIndex}, ${newIndex}`);
    console.log(JSON.stringify(order));
    order.splice(newIndex!, 0, order.splice(oldIndex!, 1)[0]);
    console.log(JSON.stringify(order));
    Sortable.get(event.target)?.sort(order, true);
    }}

    Expected behavior

    • If you drag item # 3 over # 2, then the displayed order should be what was originally 1/3/2.
    • If you drag item # 3 over # 1, then the displayed order should be 3/1/2.

Actual behavior

Information Versions react-sortable = ^6.1.4 react = ^18.2.0

Before drag: image Dragging # 3 over # 2: image Dragging # 3 over # 1 fluctuates between these states: image image

As a reference, here's what happens when I drag # 3 over # 2 if there's no onChange: image

And here's what happens if I try to use this.setState to update order: image