我已经将React DND库集成到我的React + Redux应用程序中,但是遇到一些麻烦,当DragSource离开DropTarget时发生错误。
问题是:当我将一个组件拖到目标上时,它会在输入时正确接收isOver变量,但是当我将鼠标移出该目标时,又在另一个目标上移动时,它们都将isOver变量保持为TRUE,甚至只有最后一个目标像isOver一样需要为TRUE。
奇怪的是,当我将源组件放到正确的目标上时,只有正确的目标才能接收到该项目。当我将源组件放在页面的空白部分时,也是一样,isOver会正确重置,因此仅在继续拖动时才会发生此错误。
这是我的根应用程序文件:
// Libraries
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { store } from "./store/index.js";
import { router } from "./router/index.js";
import { DragDropContextProvider } from 'react-dnd';
import MultiBackend from 'react-dnd-multi-backend';
import HTML5toTouch from 'react-dnd-multi-backend/lib/HTML5toTouch';
// Render
ReactDOM.render(
<Provider store={store}>
<DragDropContextProvider backend={MultiBackend(HTML5toTouch)}>
{router}
</DragDropContextProvider>
</Provider>,
document.getElementById('app')
);
这是DragSource组件:
// Libraries
import React from "react";
import {connect} from "react-redux";
import {compose, bindActionCreators} from 'redux';
import { DragSource } from 'react-dnd';
// Actions
import * as SystemActions from 'controllers/core/system/actions';
import * as PublisherActions from 'sections/publisher/store/actions';
// States
import mapStateToProps from 'controllers/states';
// DND Type
const Types = {
CONTACT: 'contact'
};
// DND Source
const contactSource = {
isDragging(props, monitor) {
return monitor.getItem().id === props.Contact.id;
},
beginDrag(props, monitor, component) {
const item = {
id: props.Contact.id
};
return item;
},
endDrag(props, monitor, component) {
if (!monitor.didDrop()) {
return;
}
const item = monitor.getItem();
const dropResult = monitor.getDropResult();
}
};
// DND Collect
function collect(connect, monitor) {
return {
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
};
}
export class ContactPreview extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
// Render
render() {
const {Contact, isOver, isOverCurrent, canDrop, connectDragSource} = this.props;
// Return
return connectDragSource(
<div className="contact_element">
{Contact.name}
</div>
);
}
}
function mapDispatchToProps(dispatch){
return{
SystemActions: bindActionCreators(SystemActions, dispatch),
PublisherActions: bindActionCreators(PublisherActions, dispatch)
}
}
export default compose(
DragSource(Types.CONTACT, contactSource, collect),
connect(mapStateToProps, mapDispatchToProps)
)(ContactPreview);
这是MAP循环中包含的DropTarget:
// Libraries
import React from "react";
import {connect} from "react-redux";
import {compose, bindActionCreators} from 'redux';
import { DropTarget } from 'react-dnd';
// Actions
import * as SystemActions from 'controllers/core/system/actions';
import * as PublisherActions from 'sections/publisher/store/actions';
// States
import mapStateToProps from 'controllers/states';
// DND Types
const Types = {
CONTACT: 'contact'
};
// DND Collect
function collect(connect, monitor) {
return {
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
isOverCurrent: monitor.isOver({ shallow: true }),
canDrop: monitor.canDrop(),
itemType: monitor.getItemType()
};
}
// DND Target
const tagTarget = {
drop(props, monitor, component) {
let ComponentProps = component.selector.props;
const item = monitor.getItem();
ComponentProps.PublisherActions.addTagContact('tag_preview', component.props.Tag.id, item.id);
}
};
// Module
export class TagPreview extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const {Tag, isOver, isOverCurrent, canDrop, connectDropTarget} = this.props;
return connectDropTarget(
<div className="tag_element" id={isOverCurrent ? "over":""}>
{Tag.name}
</div>
);
}
}
function mapDispatchToProps(dispatch){
return{
SystemActions: bindActionCreators(SystemActions, dispatch),
PublisherActions: bindActionCreators(PublisherActions, dispatch)
}
}
export default compose(
DropTarget(Types.CONTACT, tagTarget, collect),
connect(mapStateToProps, mapDispatchToProps)
)(TagPreview);
您可以看到此图片的问题:
All targets keeps isOver as TRUE even if the source has left
如果我将联系人拖动到所有目标(在本例中为“标签”)上,则即使我离开了目标,每个标签仍将isOver属性保持为TRUE,并且只有在放下源时它才会重置。