我正在尝试使用react-dnd
框架(?)启用DnD来创建一个简单的树视图React组件。我试过react-sortable-tree
,但因为我现在不记得的原因而抛弃它(必须自定义它,但代码对我来说太复杂了)。到目前为止,我有两个主要组件:树节点本身和由两个div
组成的丢弃覆盖,用于前后丢弃。节点编码如下:
class Node extends Component {
....
render() {
const {
data,
depth,
is_group,
connectDragSource
} = this.props;
...
for (let kid_id of kids)
childElements.push(
<ConnectedQuestionNode
id={kid_id}
is_group={areChildrenGroups}
depth={depth + 1}
key={kid_id}
/>);
return (
<Fragment>
{connectDragSource(<div
className="tree-row"
style = {{ left: treeBlockIndent * depth + 'px' }}
>
{prefix}
<div className="tree-row-title">
{data.title}
</div>
<DropOverlay
id={data.id}
nodeIsGroup={is_group}
nodeHasSubgroups={hasSubgroups}
moveActionCreator={moveQuestion}
moveGroupActionCreator={moveQuestionGroup}
nodeItemType={ItemTypes.QUESTION_NODE}
/>
</div>)}
{childElements}
</Fragment>
);
}
}
之后connect
加入ConnectedQuestionNode
(此处不相关)。这是DropOverlay
:
class _DropOverlayHalf extends Component {
render() {
const cls =
"drop-overlay"
+ (this.props.isTop ?
" top" : " bottom")
+ (this.props.isOver ?
" over" : " not-over")
+ (this.props.canDrop ?
" can-drop" : " cant-drop");
return this.props.connectDropTarget(<div className={cls}/>);
}
}
const DropOverlayHalf = DropTarget(props => props.nodeItemType, dropTargetSpec, collect)(_DropOverlayHalf);
class _DropOverlay extends Component {
render() {
return <Fragment>
<DropOverlayHalf
{...this.props}
isTop={true}/>
<DropOverlayHalf
{...this.props}
isTop={false}/>
</Fragment>
}
};
const DropOverlay = connect(null, dispatch => ({ dispatch }))(_DropOverlay);
collect
和dropTargetSpec
并不罕见。树正常呈现,但是react-dnd
的'canDrop'事件会因为每个当前呈现的DropOverlayHalf而以某种方式触发。而且,monitor.isOver()
总是返回false。我不知道如何处理这个问题。也许我会尝试重写它,以便所有内容都嵌套而不是我目前拥有的缩进列表。希望一些狂野的React大师出现并指出我正确的方向:)
更新:hover
根本没有触发,这意味着问题是monitor.isOver()
。