如何在反应拖放中访问拖动的对象字段?

How to access dragged object fields in react drag and drop?

所以基本上我是想在一个简单的游戏中使用 dnd,但我觉得我不太明白某些参数的意义。我有两个组件用作源和目标。源正在从父级接收一个单元道具,我希望 Field 组件(目标)知道正在拖动哪个单元 atm 并在放置后将其显示在其中。我已经看到我可以在 beginDrag() 中指定一些字段,但我认为它可能不是。有可能还是有解决方法?

const BenchTileSource = {
  beginDrag(props) {
    // Return the data describing the dragged item
    const item = { unit: props.unit };
    return item;
  }
};

const TileBackground = styled.div`
    ...
`;

function UnitBenchTile({ unit }) {
  const [{ isDragging }, drag] = useDrag({
    item: { type: TileTypes.BENCH_TILE },
    collect: monitor => ({
      isDragging: !!monitor.isDragging()
    })
  });
  return unit ? (
    <TileBackground ref={drag}>{unit.name}</TileBackground>
  ) : (
    <TileBackground />
  );
}

export default BenchTileSource(
  TileTypes.BENCH_TILE,
  BenchTileSource
)(UnitBenchTile);


import React from "react";
import styled from "styled-components";
import { connect } from "react-redux";
import { TileTypes } from "../dragTypes/TileTypes";
import { useDrop } from "react-dnd";

const mapStateToProps = function(state) {
  return {
    currentPosition: state.currentPosition,
    unitsPositions: state.unitsPositions
  };
};

  ...

function Field({ index, children, dispatch }) {
  const unitsPositions = useSelector(
    state => state.unitsPositionsReducer.unitsPositions
  );

  const [{ isOver }, drop] = useDrop({
    accept: TileTypes.BENCH_TILE,
    drop: monitor => setCurrentPosition([x, y], monitor.getItem()),
    collect: monitor => ({
      isOver: !!monitor.isOver(),
      item: monitor.item
    })
  });

  const setCurrentPosition = (newPosition, unit) => {
    if (!unitsPositions[index].unit) {
      const result = unitsPositions;
      result[index] = { position: newPosition, unit: unit };
      dispatch({ type: "UPDATE_UNITS_POSITIONS", result });
    }
  };

  const isRight = (index - 9) % 10 === 0;
  const isBottom = index >= 50;
  const x = index % 10;
  const y = Math.floor(index / 6);

  if (isRight && isBottom)
    return <FrameBottomRight ref={drop}>{children}</FrameBottomRight>;
  else if (isRight) return <FrameRight ref={drop}>{children}</FrameRight>;
  else if (isBottom) return <FrameBottom ref={drop}>{children}</FrameBottom>;
  else return <Frame ref={drop}>{children}</Frame>;
}

export default connect(mapStateToProps)(Field);

react-dnd 的监视器可以访问所有需要的信息。在这种情况下,您想要访问目标中当前拖动的源,因此您必须使用 DropTargetMonitor 的方法 getItem(),它将 return item 中定义的所有属性 属性 被拖动的源。如果您已经在项目中定义了 id,那么在拖动操作开始时无需提供额外的字段,该字段足以识别正在拖动的项目。

更新 如果你真的想传递额外的字段,你可以简单地合并项目数据,方法是在你的 begin 方法中将它“传播”到一个新对象以及你的额外数据。

return {
  ...monitor.item,
  additional: data
}