【问题标题】:How to save the state of drag and drop rows in React?如何在 React 中保存拖放行的状态?
【发布时间】:2021-09-10 07:20:21
【问题描述】:

我是一个初学者,目前,我正在尝试学习如何使表格的行可拖动和重新排列。我正在使用 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;

【问题讨论】:

    标签: reactjs react-beautiful-dnd


    【解决方案1】:

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

    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 };
    }
    

    比你像这样创建&lt;Draggable&gt; 列表:

    {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) 编写一个函数来重新排序列表。请注意,该函数应返回一个新数组(不仅仅是更改现有数组),以便您可以将其存储在组件状态中。这是一个例子:

    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 函数来获取一个新的、重新排序的数组并将其存储在组件状态中。这将导致表重新呈现。这里是整个更新的组件:

    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

    【讨论】:

    • @Hawra Saif 我刚刚意识到在我的回答中我将你的类组件更改为一个函数组件......希望这对你来说不是问题。
    • 感谢您的解决方案。但是我需要将它实现为类组件,这里唯一重要的是 useState 钩子,因为它不能在类组件中使用。那么有什么解决方法呢?
    • 将答案更新为类组件。 Stackblitz 也是如此。
    • 非常感谢!您的解决方案帮助我理解了很多事情。
    • 很高兴为您提供帮助。如果它解决了您的问题,请考虑接受答案。
    猜你喜欢
    • 2012-04-13
    • 1970-01-01
    • 2019-08-24
    • 2013-12-09
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    相关资源
    最近更新 更多