要考虑的要点:
所以,问题是在下面的实现中,拖动时,没有调用itemSource的endDrag()方法。
可能的解决方案是创建不同的(但实际上相同的)组件,这些组件仅按项类型不同,将这些组件导入Container组件并根据props.itemType安装 - 因此,它不是DRY选项。
问题是: 1.怎么做对吗?如何重用和渲染一个可拖动的组件,它们依赖于DragSource / DropTarget中的Container的props itemType? 2.为什么下面的解决方案不起作用?为什么没有调用endDrag()方法?
Container.js:
import React, { Component } from 'react';
import { DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import Item from './Item';
import ItemDndDecorator from './ItemDndDecorator';
const style = {
width: 333,
};
class Container extends Component {
state = {some: true}
hoverHandle = () => {
this.setState({some: !this.state.some})
}
render() {
const Item1 = ItemDndDecorator(Item, 'item1')
const Item2 = ItemDndDecorator(Item, 'item2')
window.hoverHandle = this.hoverHandle
return (
<div style={style}>
<Item1>
<Item2>
some text 1
</Item2>
</Item1>
</div>
);
}
}
export default DragDropContext(HTML5Backend)(Container)
Item.js:
import React from 'react';
const style = {
border: '1px dashed gray',
padding: '1rem',
margin: '1rem',
cursor: 'move',
};
function Item(props) {
const { connectDragSource, connectDropTarget } = props;
return connectDragSource(connectDropTarget(
<div style={style}>
{props.children}
</div>,
));
}
export default Item
ItemDnDDecorator.js:
import { DragSource, DropTarget } from 'react-dnd';
const itemSource = {
beginDrag(props) {
console.log('begin drag');
return { id: props.id } ;
},
endDrag() {
console.log('end drag');
}
};
const itemTarget = {
hover() {
window.hoverHandle()
}
};
function ItemDndDecorator(component, itemType) {
return (
DropTarget(itemType, itemTarget, connect => ({
connectDropTarget: connect.dropTarget(),
}))(
DragSource(itemType, itemSource, (connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging(),
}))(component))
)
}
export default ItemDndDecorator