拖动以重新排序并使用reactjs保存状态

拖动以重新排序并使用reactjs保存状态,reactjs,Reactjs,我正在编写一个使用react-sortable hoc的小应用程序 一切都很好,但我在按顺序显示列表时遇到问题 我有 user 0 user 1 user 2 当我将用户2拖动到用户0上方时 而不是 user 2 user 0 user 1 我明白了 我认为这与我在州里设定秩序的方式有关。但我想不出来 这是我在排序端设置顺序的方式 const onSortEnd = ({ oldIndex, newIndex }) => { setUsers(prevState =>

我正在编写一个使用react-sortable hoc的小应用程序

一切都很好,但我在按顺序显示列表时遇到问题

我有

user 0
user 1
user 2
当我将用户2拖动到用户0上方时 而不是

user 2
user 0
user 1
我明白了

我认为这与我在州里设定秩序的方式有关。但我想不出来

这是我在排序端设置顺序的方式

const onSortEnd = ({ oldIndex, newIndex }) => {

    setUsers(prevState => {
        const newItems = [...prevState];
        newItems[newIndex].order = oldIndex;
        newItems[oldIndex].order = newIndex;
        return newItems.sort((a, b) => a.order - b.order);
    })
};
这是正在运行的应用程序,您可以使用它。
您要做的是交换

如果只想在新位置“插入”元素,则必须更新两个位置之间的所有项目

在您的情况下,一种方法是只移动元素并为所有项目重新创建订单

setUsers(prevState => {
  const newItems = [...prevState];
  newItems.splice(newIndex, 0, newItems.splice(oldIndex, 1)[0]).forEach((item,index)=>{
    item.order = index;
  });

  return newItems
});
演示在

我已经修复了它, 下面是要使用的工作url

您猜测问题出在
onSortEnd
函数上是正确的。我们不需要交换newIndex和oldIndex的位置,只需要向上或向下调整它们

这是一个工作代码,可以稍微清理一下,但您的想法是:)

const onSortEnd=({oldIndex,newIndex})=>{
setUsers(prevState=>{
const newItems=[…prevState];
如果(旧索引>新索引){
for(设i=oldIndex-1;i>=newIndex;i--){
newItems[i].order++;
newItems[oldIndex]。订单=newIndex;
}
}else if(旧索引<新索引){
for(设i=oldIndex+1;i a.顺序-b.顺序);
});
};

希望有帮助。快乐编码:)

因此看起来您的代码只是简单地交换元素。这似乎不是您真正想要做的。事实上,您确实想要删除元素并将其插入到给定位置。我认为,既然您已经有了oldIndex和newIndex,您可以按如下方式处理排序函数:

  const onSortEnd = ({ oldIndex, newIndex }) => {
    setUsers(prevState => {
      var newItems = [...prevState];
      let elem = newItems[oldIndex]
      newItems.splice(oldIndex, 1)
      newItems.splice(newIndex, 0, elem)

     return newItems 
    });
  };

实际上不需要顺序,而且捕获的状态超过了所需的最低状态(除非在其他地方使用)。

此示例不起作用。我不仅仅讨论新元素。这很“简单”,因为我只是将其添加到数组的末尾(顺序为:array.length)@我在回答中发布的代码运行良好,我发布的链接存在问题(它没有保存我的代码)。我已经更新了链接。是的,我以前也遇到过。codesandbox需要自动保存:)那么..你正在更新所有元素,对吗?我也看不到。订单已更新,我需要它,因为我将所有内容发送到数据库,以便在
forEach
中保存这些内容,而
订单
就是更新的地方。我不明白,但它是有效的。让我看看我去拿些咖啡,然后再读一遍:):)好:)它只是在所有元素上循环,然后一个接一个地向上或向下移动它们,最后将拖动的元素移动到新位置:)很好……我需要console.log只记录更改的元素(因为我会将它们保存到数据库中)你能帮个忙吗?谢谢!你是怎么想的…const newItems=[…prevState];const changed=[]newItems[oldIndex]。order=newIndex;changed.push(newItems[oldIndex]);if(oldIndex>newIndex){for(let i=oldIndex-1;i>=newIndex;i--){newItems[i]。order++;changed.push(newItems[i])}else如果(oldIndex顺序,因为你使用数组,数组是有序类型。是的,但我需要将数据以正确的顺序保存在数据库中,由于我不能删除和添加记录,因此我需要使用订单密钥来保持订单。谢谢!
const onSortEnd = ({ oldIndex, newIndex }) => {
    setUsers(prevState => {
      const newItems = [...prevState];

      if (oldIndex > newIndex) {
        for (let i = oldIndex - 1; i >= newIndex; i--) {
          newItems[i].order++;
          newItems[oldIndex].order = newIndex;
        }
      } else if (oldIndex < newIndex) {
        for (let i = oldIndex + 1; i <= newIndex; i++) {
          newItems[i].order--;
          newItems[oldIndex].order = newIndex;
        }
      }
      return newItems.sort((a, b) => a.order - b.order);
    });
  };
  const onSortEnd = ({ oldIndex, newIndex }) => {
    setUsers(prevState => {
      var newItems = [...prevState];
      let elem = newItems[oldIndex]
      newItems.splice(oldIndex, 1)
      newItems.splice(newIndex, 0, elem)

     return newItems 
    });
  };