粗略总结,我使用以下结构(使用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
似乎完全被替换。
由于拖动元素也是MyComponent
的子元素,因此它也会被替换,拖动操作也会失败。
如果我将以下代码放在MyComponent
中,一切正常:
shouldComponentUpdate: function(nextProps) {
if (nextProps.draggingElement !== this.props.draggingElement) {
return false;
}
return true;
},
但是现在DropTargets也不再重新渲染(因为它们是MyComponent
的孩子),并且不会显示所需的信息。
我该怎么办?具体而言,如果新属性仅影响其中的一小部分,为什么MyComponent
的DOM被完全替换?