3

需要考虑的要点:

  • 这个例子是虚构的,但说明了问题。
  • 在实际应用程序中使用全局存储,并且在 itemTarget 的 hover() 方法中发出动作更改。这里,为了模拟全局存储,使用了 window 对象。
  • 不允许使用 ES7 装饰器(或其他 ES7 语法)。

所以,问题是在下面的实现中,当拖动时,没有调用 itemSource 的 endDrag() 方法。
可能的解决方案是创建不同(但实际上相同)的组件,这些组件仅因项目类型而异,将这些组件导入到 Container 组件并根据 props.itemType 进行挂载——因此,它不是 DRY 选项。

问题是: 1. 怎么做才对?如何在 DragSource/DropTarget 中重用和渲染依赖于 Container 的 props itemType 的可拖动组件?2. 为什么下面的解决方案不起作用?为什么没有调用 endDrag() 方法?

容器.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)

项目.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
4

0 回答 0