粗略总结一下,我使用的是如下结构(使用 Redux):
<Provider store=..>
<MyApp>
<Connect(DragDropContext)>
<DragDropContext>
<div id=main>
<DragLayer></DragLayer>
<MyComponent props={draggingElement:store.draggingElement}>
<div class=container>
<DropTarget props={draggingElement:this.props.draggingElement}>
<div id=indicator>
Currently dragging #2 which can be dropped here
</div>
</DropTarget>
<div id=elements>
<DragSource key=1></DragSource>
<DragSource key=2></DragSource>
<DragSource key=3></DragSource>
</div>
</div>
<div class=container>
<DropTarget props={draggingElement:this.props.draggingElement}>
<div id=indicator>
Currently dragging #2 which can not be dropped here.
</div>
</DropTarget>
<div id=elements>
<DragSource key=1></DragSource>
<DragSource key=2></DragSource>
<DragSource key=3></DragSource>
</div>
</div>
</MyComponent>
</div>
</DragDropContext>
</Connect(DragDropContext)>
</App>
</Provider>
现在,在所有 DragSources 中,我正在监听beginDrag
事件并触发一个操作,该操作使用有关当前正在拖动的项目的一些信息更新存储 ( draggingElement
)。
MyComponent
获取此信息作为属性传递,但除了将其传递给所有 DropTargets 外,不以任何方式使用它,仍然作为属性。现在,在所有 DropTargets 中,我根据被拖动的元素是否可以拖放到那里来呈现一条消息。
到目前为止一切顺利,不幸的是,一旦我开始拖动一个元素,我就会收到以下错误消息:
Uncaught TypeError: Cannot read property 'nodeName' of undefined
at Object.a [as getDragPreviewOffset] (core-2fc0801472.js:31485)
at t.handleTopDragStart (core-2fc0801472.js:31485)
似乎MyComponent
一旦它收到带有有关拖动元素的信息的属性,它就会在 DOM 中完全被替换。并且由于拖动元素也是 的子元素MyComponent
,因此它也会被替换并且拖动操作失败。如果我将以下代码放入MyComponent
一切正常:
shouldComponentUpdate: function(nextProps) {
if (nextProps.draggingElement !== this.props.draggingElement) {
return false;
}
return true;
},
但是现在 DropTargets 也不再重新渲染(因为它们是 的子级MyComponent
)并且不显示所需的信息。
我能做些什么呢?MyComponent
具体来说,如果新属性只影响其中的一小部分,为什么要完全替换 DOM ?