反应DnD。如何将itemTypes传递给依赖于容器道具的DragSource / DropTarget?

时间:2017-04-28 21:29:00

标签: reactjs drag-and-drop react-dnd

要考虑的要点:

  • 该例子已经解决,但说明了问题。
  • 在实际应用中,使用全局存储,并在itemTarget的hover()方法中发出操作更改。在这里,模仿全球 存储,使用窗口对象。
  • 使用ES7装饰器(或其他 不允许使用ES7语法。

所以,问题是在下面的实现中,拖动时,没有调用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

0 个答案:

没有答案