React-dnd: 如何调试“挂断后无法呼叫悬停”?

创建于 2016-04-19  ·  24评论  ·  资料来源: react-dnd/react-dnd

你好
我的一位同事能够以某种方式打破监视状态,即使鼠标悬停并认为仍处于悬浮状态,它也会认为它处于悬停状态:

screenshot 2016-04-19 16 34 56

关于从哪里开始调试的任何想法? 我无法复制它,他每周看到一次。
我正在使用触摸后端切换来处理鼠标事件以及一些调整。

triage wontfix

最有用的评论

我也有这个问题-我的情况是React组件既是放置目标又是拖动源。 当我有两个组件时,可以在它抛出上述错误之前拖放一次。 当我有三个时,它可以正常工作。 我认为这与单个组件上的多个上下文有关?

所有24条评论

因此,研究了JS问题后,我发现在此错误之前,当应该进行放置时,用户定义的回调引发了一个错误,该错误可能破坏了监视器/存储的状态。

我也有这个问题-我的情况是React组件既是放置目标又是拖动源。 当我有两个组件时,可以在它抛出上述错误之前拖放一次。 当我有三个时,它可以正常工作。 我认为这与单个组件上的多个上下文有关?

我遇到了这个问题,昨晚我针对我的特定用例找到了解决方法。

就上下文而言,我正在渲染一个DragSources列表,如果任何拖放到DropTarget上的东西都将被从DragSources列表中删除,并且DropTarget将被呈现DragSource内容的组件替换。

拖放功能的重要部分(这是将“类别”与项目匹配的组件)是一项将项目添加回DragSource列表的功能,该功能只需将放置的项目替换为DragSource并将其添加回DragSources清单。

image

现在,仅当我将项目放在所有类别中并删除至少一个项目时才发生此异常(当列表不完整时,我将删除一个项目然后再次将其重新添加),则不会发生此异常。 因此,我得出的结论是,DragSources列表永远不可能有零个子代(可能是由于容器元素消失了,但是我没有足够的时间来测试)。 为了缓解这种情况,我没有将其放置在DragSources列表中,而是将它们的样式设置为display: none

这很难解释,但我希望这会有所帮助。

我正在体验与@PendragonDevelopment相同的效果。 我的列表从一个项目开始,然后添加到另一个项目,然后可以重新排列。 您只能一次重新排列这两项,然后再开始看到Javascript错误,并且再也不能重新排列它们的顺序。

我也有这个问题
我不知道为什么,但是在第一次重新排列后,我看到了这些错误

我在这里遇到了同样的错误。

在对演示示例和我的示例进行一些比较之后,我发现当我循环组件时,我使用数组键设置了组件索引,并且在演示中,他们仅设置了索引Sortable / Simple / Container.js是固定的。

做到了,工作了!

该键必须是固定值,因为如果不是,则在对数组重新排序后会松散对组件的引用。

动态创建和附加DnD组件后,您必须使用某些库,否则Date.now()会为每个组件生成唯一键而使用它。

{this.state.rows.map(function(row, key) {
  return (<RowComponent key={row.id} index={key} id={row.id} moveRow={that.moveRow} />);
})}

每个组件的row.id都是唯一的

我不明白为什么会这样,但是使用了我的model.id而不是node-uuid's v4生成的随机密钥修复了它。 至少我没有错误了。

修复钥匙并不能解决我的问题。
这是我的代码

           <ContentPatch>
             {tasks.loading 
              ? <div>...loading </div>
              : this.state.containers.map((item, i) => {
                  return (
                    <TaskStage
                      key={item.id}
                      item={item}
                      tasklist={tasks.tasks}
                      onDropped={this.handleDropped}
                      onBeginningDrag={this.onBeginningDrag}
                    />
                  );
                })}
          </ContentPatch>

每次执行删除操作后,我都在映射所有项目,并且遇到相同的错误。
然后我改变了条件

...
{tasks.loading && tasks.tasks.length===0
 ? <div>...loading </div>
...

解决了我认为,再次安装是此错误的原因。

我遇到了同样的错误。

我的用例是:

  • 相同的DragSourceDragTarget组件
  • 在放下时,我想导航到一条路线

原来endDragDragSource方法)dropDropTarget方法)之后触发。 我正在drop内处理路线导航,这破坏了显示器的状态。

将该逻辑移至endDrag进行了修复。 重构涉及检查放置是否已完成monitor.didDrop() ,但还算不错。

我也有这个问题。 我的情况是组件既是放置目标又是拖动源。 我尝试使用endDrag方法并尝试使用修补的后端(https://gist.github.com/nickpresta/eb5cce69d650db4c2795)。 它没有解决这个问题。

我的组件:

@DropTarget<HeadColOwnProps>(TaskDndTypes.headCol, headColTargetSpec, headColTargetCollector)
@DragSource<HeadColOwnProps>(TaskDndTypes.headCol, headColSourceSpec, headColSourceCollector)
class HeadColComponent extends React.Component<any, void> {
    render() {
        const props = this.props;
        return this.props.dndConnectDropTarget(
            this.props.dndConnectDragPreview(
                <div>
                    <div className={block('panels-task__drag')({start: props.dndIsDragging})}>
                        <SortingIcon
                            label={props.label}
                            arrowIsVisible={props.sortingIsPossible}
                            direction={props.sortingDirection}
                            clickHandler={props.sortingHandler}
                        />
                        {this.props.dndConnectDragSource(
                            <span className="panels-task__drag-control">
                                <SVGIcon width={10} height={10} url={'#icon-drag-and-drop-cell'} />
                            </span>
                        )}
                    </div>
                </div>
            )
        );
    }
}

使用示例:

const renderHeadCellId = (): JSX.Element => {
        return (
            <TaskCellHead key="key-head-col-id" modifications={{ number: true }}>
                <HeadColComponent
                    label="#"
                    key="key-dnd-head-col-id"
                    taskColType={TaskCols.id}
                    sortingIsPossible={false}
                    taskColsOrder={taskStore.orderCols}
                    updateDragProcess={(dp: TaskColDragProcess | null) => taskStore.updateDragProcess(dp)}
                    updateOrderCols={(order: TaskCols[]) => taskStore.updateOrderCols(order)}
                    dragProcess={taskStore.dragProcess}
                />
            </TaskCellHead>
        );
    };

装饰器设置:

const headColSourceSpec: DragSourceSpec<HeadColOwnProps> = {
    beginDrag(props: HeadColOwnProps): DraggedItem {
        return { sourceColType: props.taskColType };
    },
    canDrag(props: HeadColOwnProps): boolean {
        return props.taskColsOrder.length > 1;
    },
    endDrag(props: HeadColOwnProps, monitor: DragSourceMonitor): void {
        console.debug('endDrag');
        if (!monitor.didDrop()) {
            return;
        }
        console.debug('endDrag finish');
        props.updateOrderCols((monitor.getDropResult() as DroppedResult).newOrderCols);
    }
};

const headColTargetSpec: DropTargetSpec<HeadColOwnProps> = {
    drop(props: HeadColOwnProps, monitor: DropTargetMonitor): DroppedResult {
        console.debug('drop');
        return {
            newOrderCols: getNewOrder((monitor.getItem() as DraggedItem).sourceColType, props.taskColsOrder, props.dragProcess)
        };
    },
    hover(props: HeadColOwnProps, monitor: DropTargetMonitor, component: HeadColComponent): Object | void {
        if (!monitor.canDrop()) {
            return;
        }
        // ...
        props.updateDragProcess(currentDragProcess);
    },
    canDrop(props: HeadColOwnProps, monitor: DropTargetMonitor): boolean {
        return props.taskColType !== (monitor.getItem() as DraggedItem).sourceColType;
    }
};

const headColSourceCollector = (connect: DragSourceConnector, monitor: DragSourceMonitor) => ({
    dndConnectDragSource: connect.dragSource(),
    dndConnectDragPreview: connect.dragPreview(),
    dndIsDragging: monitor.isDragging()
});

const headColTargetCollector = (connect: DropTargetConnector, monitor: DropTargetMonitor) => {
    return {
        dndConnectDropTarget: connect.dropTarget(),
        dndIsOverCurrent: monitor.isOver({ shallow: true })
    };
};

我注意到重新排列后不会调用endDrag ,而是会调用drop 。 这些行从不执行:

endDrag(props: HeadColOwnProps, monitor: DragSourceMonitor): void {
        console.debug('endDrag');
        if (!monitor.didDrop()) {
            return;
        }
        console.debug('endDrag finish');
        props.updateOrderCols((monitor.getDropResult() as DroppedResult).newOrderCols);
    }

我究竟做错了什么? 有任何想法吗?

我将HTML5Backend替换为Touch Backend(https://github.com/yahoo/react-dnd-touch-backend)。 这个对我有用。

对我来说,我得到这个错误仅仅是因为在drop的回调中设置了断点。 有趣的是,即使所有断点都继续并且浏览器没有暂停,它也会失败。 一旦删除断点,错误就消失了。

我有同样的问题。 用react-dnd-touch-backend替换了这个包,但这并没有真正解决问题。 我宁愿运行html5。 尝试对迭代器正在打印的所有元素设置键。

我遇到了同样的错误。 我在每个渲染器的可拖动组件上重新应用了HOC,因此它们始终是不同的,这混淆了react-dnd。

@hakunin您是否解决了此问题(我也仅在发生另一个运行时错误后才收到此错误)。

此后,我已经重构了所有的DnD代码,当我开始拖动时仍然可以得到它。 现在,我将所有代码都移到了一个util文件中,并使其可配置,我也许终于可以找到它在某些时候发生的原因。 我会在这里发布有关它的信息。 (我在鼠标设置btw中使用TouchBackend)

感谢您的回复。 只有在拖动时发生其他一些错误后,我才会出现此错误-在这一点上似乎无法恢复。 对你来说一样吗?

每当我开始拖拽时,我都会抱怨。

我的情况是,删除项目后,endDrag(props,monitor,component)中的组件未定义。 因此,这导致了我的原始错误,该错误导致控制台流出现“丢弃后无法调用悬停”消息。

感谢以下评论,我已经能够解决此问题: https :

我之前引起其他未捕获的错误时遇到了这个问题。没有其他错误时就没有此错误。

就我而言,它发生在endDrag中,我调用了一些导致错误的动作/函数。 因此,基本上未捕获的错误使dnd卡住了。 您可以在endDrag块中调用某些函数/操作时使用try catch。
endDrag: (props, monitor) => { try { handleEndDrag(); } catch(errror) { console.error(error)} }

对我来说,onDrop函数中的调试器语句也是错误的根源。 删除它会使错误消失,但是如果没有它,我将很难调试。

知道为什么调试器会触发此错误吗?

不知道是否有任何兴趣,但我正在运行Electron应用程序。

由于此问题最近没有活动,因此已被自动标记为陈旧。 如果没有进一步的活动,它将关闭。 感谢您的贡献。

此页面是否有帮助?
0 / 5 - 0 等级