Я интегрировал библиотеку React DND в свое приложение React + Redux, но у меня возникли проблемы с устранением ошибки, возникающей, когда DragSource покидает DropTarget.
Проблема в том, что, когда я перетаскиваю компонент над целью, он правильно получает переменную isOver при входе, но когда я перемещаю мышь, оставляя эту цель, и я перемещаюсь над другой целью, они оба сохраняют переменную isOver.как ИСТИНА, даже если только последняя цель должна иметь значение ИСТИНА как isOver.
Странно то, что, когда я отбрасываю исходный компонент на правильную цель, только правильная цель получает элемент.То же самое, когда я перетаскиваю исходный компонент на пустую часть страницы, 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);
Вот DropTarget, который содержится в цикле MAP:
// 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);
Вы можете увидеть проблему с этим изображением:
Для всех целей isOver сохраняет значение TRUE, даже если источник оставил
. Если я перетаскиваю контакт на все цели (в данном случае теги), каждый тег сохраняет реквизит isOver как TRUE, даже еслиоставил цель, и она сбрасывается, только если я уронил источник.