React 中如何保存拖放行的状态?

How to save the state of drag and drop rows in React?

我是初学者,目前,我正在尝试学习如何使 table 的行可拖动和重新排列。我正在使用 react-beautiful-dnd 库。我能够使行可拖动,但我无法在拖放后保存行的状态。 如果对此有任何帮助,我将不胜感激。

import { Component } from 'react';
import React from 'react';
import './App.css';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

class App extends Component
{

  drawTable = () => {
    return (
    <div>
      <DragDropContext>
      <Droppable droppableId="Table">
        {(provided) => (
    <table {...provided.droppableProps} ref={provided.innerRef}>
      <Draggable draggableId='1' index={1}>
      {(provided) => (
      <tr ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      )}
      </Draggable>
      <Draggable draggableId='2' index={2}>
        {(provided) => (
      <tr ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      )}
      </Draggable>
      <Draggable draggableId='3' index={3}>
        {(provided) => (
      <tr ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
        <td>3</td>
        <td>Larry the Bird</td>
        <td>@twitter</td>
      </tr>
      )}
      </Draggable>
     {provided.placeholder} 
    </table>
    )}
    </Droppable>
    </DragDropContext>
  </div>
   
  );
  
  }


render = () => {

    return (
      <div>
        {this.drawTable()}
      </div>
    );

  }
}


export default App;

(1) 首先,将您的项目列表存储在组件状态中,并使您的 table 行动态化。除了更 DRY 之外,您还可以在每次列表顺序更改时重新呈现 table 行:

startingList = [
    {
      id: '1',
      fName: 'Mark',
      lName: 'Otto'
    },
    {
      id: '2',
      fName: 'Jacob',
      lName: 'Thornton'
    },
    {
      id: '3',
      fName: 'Larry',
      lName: 'Bird'
    }
];
constructor(props) {
  super(props);
   this.state = { items: this.startingList };
}

比起像这样创建 <Draggable> 列表:

{this.state.items.map((item, index) => (
     <Draggable key={item.id} draggableId={item.id} index={index}>
         {provided => (
              <tr
                    ref={provided.innerRef}
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
               >
                    <td>{item.id}</td>
                    <td>{item.fName}</td>
                    <td>{item.lName}</td>
               </tr>
         )}
     </Draggable>
 ))}

(2) 添加 onDragEnd 事件处理程序。处理程序将收到一个包含一些有用信息的对象,尤其是拖动项的 id、目标和源,并将使用该信息对列表重新排序:

onDragEnd = e => {
    ...
};

...
<DragDropContext onDragEnd={this.onDragEnd}>...</DragDropContext>

(3) 写一个函数重新排序列表。请注意,该函数应 return 一个新数组(不仅仅是更改现有数组),以便您可以将其存储在组件状态中。这是一个例子:

reorder = (list, startIndex, endIndex) => {
  const result = Array.from(list);
  const [removed] = result.splice(startIndex, 1);
  result.splice(endIndex, 0, removed);

  return result;
};

(4) onDragEnd 将调用 reorder 函数来获取一个新的、重新排序的数组并将其存储在组件状态中。这将导致 table 重新呈现。这里是整个更新的组件:

class App extends React.Component {
  startingList = [
    {
      id: '1',
      fName: 'Mark',
      lName: 'Otto'
    },
    {
      id: '2',
      fName: 'Jacob',
      lName: 'Thornton'
    },
    {
      id: '3',
      fName: 'Larry',
      lName: 'Bird'
    }
  ];
  constructor(props) {
    super(props);
    this.state = { items: this.startingList };
  }

  onDragEnd = e => {
    console.log(e);
    if (!e.destination) {
      return;
    }
    const { items } = this.state;
    const sorted = this.reorder(items, e.source.index, e.destination.index);
    console.log(sorted);
    this.setState({
      items: sorted
    });
  };

  reorder = (list, startIndex, endIndex) => {
    const result = Array.from(list);
    const [removed] = result.splice(startIndex, 1);
    result.splice(endIndex, 0, removed);

    return result;
  };

  render() {
    return (
      <div>
        <DragDropContext onDragEnd={this.onDragEnd}>
          <Droppable droppableId="Table">
            {provided => (
              <table {...provided.droppableProps} ref={provided.innerRef}>
                <tbody>
                  {this.state.items.map((item, index) => (
                    <Draggable
                      key={item.id}
                      draggableId={item.id}
                      index={index}
                    >
                      {provided => (
                        <tr
                          ref={provided.innerRef}
                          {...provided.draggableProps}
                          {...provided.dragHandleProps}
                        >
                          <td>{item.id}</td>
                          <td>{item.fName}</td>
                          <td>{item.lName}</td>
                        </tr>
                      )}
                    </Draggable>
                  ))}
                  {provided.placeholder}
                </tbody>
              </table>
            )}
          </Droppable>
        </DragDropContext>
      </div>
    );
  }
}

工作stackblitz