如何在React中拖放多个元素?

时间:2019-04-18 17:03:50

标签: javascript reactjs drag-and-drop

这是我关于StackOverflow的第一个问题。我想用React构建一个小游戏,用户可以将Tetrominos拖放到网格上,还可以根据自己的喜好重新放置或旋转它们。 tetrominos由矩阵表示,然后每个块都在li元素中呈现。

z-tetromino的示例: [0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0]

不幸的是,我还不能发布图片,这会使事情变得更容易。

网格太用矩阵表示。

现在我要做的基本上是将这些块矩阵拖放到网格上,以便网格中的值相应更改(0→1等)。

问题是,我不知道如何使用标准HTML5 DnD API或React DnD一次拖动多个li元素。当用户单击某个四联蛋白的一个li元素时,整块都应该移动。也许我可以使用jQuery UI来解决此问题,但是由于在React中不允许直接进行DOM操作,所以我想知道如何做到这一点。

我试图将一个块拖动到半最佳工作的网格上,因为一个块代替了整行的网格块,即使使用display:inline-block在CSS中设置。

这是第一个实验中的一些简单代码。

onDragStart = e => {
    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData('text', e.target.id);
    // e.dataTransfer.setDragImage(e.target.parentNode, 20, 20);
  };

  handleDrop = e => {
    const pieceOrder = e.dataTransfer.getData('text');
    // console.log(document.getElementById(pieceOrder));
    // e.target.appendChild(document.getElementById(pieceOrder));
    // console.log(pieceOrder);
    e.target.replaceWith(document.getElementById(pieceOrder));
    e.target.remove();
  };

renderEmptyBoardCell(i) {
    return (
      <li key={i} className="emptyBoardCell" onDragOver={(e) => e.preventDefault()} onDrop={(e) => this.handleDrop(e)}>></li>
    );
  }

  renderTemplateBoardCell(i) {
    return (
      <li key={i} className="templateBoardCell" onDragOver={(e) => e.preventDefault()} onDrop={(e) => this.handleDrop(e)}>></li>
    );
  }

  renderEmptyCell(i) {
    return (
      <li key={i} className="emptyCell"></li>
    );
  }

  renderFilledCell(piece_config, i) {
    return (
      <li key={i} id={i} className={`filledCell ${piece_config}`} draggable onDragStart={this.onDragStart}></li>
    );
  }

问题是,从理论上讲,使用React DnD或任何其他库都可以吗?如果是,一次对DnD多个元素的近似解决方案是什么。

感谢您的时间!

4 个答案:

答案 0 :(得分:1)

您只能使用react-dnd一次拖动一个项目。要么使用其他库,要么以某种方式将不同的片段组合到一个项目中,然后将其拖放。

答案 1 :(得分:0)

我知道有点晚了,但是您是否已经调查过:panResponder。我正在研究多个d'n'd元素,而panResponder最有可能适合

答案 2 :(得分:0)

react-beautiful-dnd是满足您需求的不错选择。

答案 3 :(得分:0)

万一有人要在2020年寻找解决方案。这是我的current solutionreact-dnd并做出反应。您可以尝试现场演示here

这是另一个更简单的示例,您可以查看codesandbox here