如何在反应拖放中访问拖动的对象字段?
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
}
所以基本上我是想在一个简单的游戏中使用 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
}