Как исправить состояние React DND при перетаскивании, когда источник покидает цель? - PullRequest
0 голосов
/ 20 сентября 2018

Я интегрировал библиотеку 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, даже еслиоставил цель, и она сбрасывается, только если я уронил источник.

...