React元素类型无效

时间:2018-08-23 18:09:41

标签: javascript reactjs react-dnd

我无法弄清楚这段代码出了什么问题。我正在尝试为reactDND DragSource HOC编写一个简单的包装器组件。目标是能够编写以下代码:

const CanDrag = () => (
  <Draggable type='FOO' source={{id: 1}} collector = {() => ({})} >
     <div>whatever</div>
  </Draggable>
);

不必写

DragSource(type, source, collector)(CanDrag);

对于我的特定用例,前者更方便。这是我写的包装器组件:

import { DragSource } from 'react-dnd';
import { Component, Fragment } from 'react';

// A component that wraps its children in a draggable HOC
export default class Draggable extends Component {
  DraggableItem = null;

  static propTypes = {
    type: propTypes.string.isRequired,
    source: propTypes.object.isRequired,
    collector: propTypes.func.isRequired,
    children: propTypes.oneOf([
      propTypes.node,
      propTypes.element,
      arrayOf([
        propTypes.oneOf([
          propTypes.node,
          propTypes.element,
        ]),
      ]),
    ]),
  };

  componentWillMount() {
    const {
      type,
      source,
      collector,
      children,
    } = this.props;
    this.DraggableItem = DragSource(type, source, collector)(<Fragment>{ children }</Fragment>);
  }

  render() {
    const { DraggableItem } = this;
    return <DraggableItem />;
  }
}

我不断收到此错误:

  

元素类型无效:应使用字符串(对于内置组件)或类/函数(对于复合组件),但得到:对象。

1 个答案:

答案 0 :(得分:2)

DragSource HOC需要一个组件或函数,但是您传递了一个渲染的节点<Fragment>{ children }</Fragment>,它是一个对象而不是一个组件。

这样做完全没有用,因为被包装的组件需要实现某个接口。因此,您不能仅将任意组件传递给它,因为它们不会消耗HOC注入的道具。

如何将HOC转换为以render prop作为唯一子元素的组件:

const Draggable = ({ type, spec, collect, children }) => {
    const Source = DragSource(type, spec, collect)(
        ({ connectDragSource, isDragging }) => connectDragSource ? connectDragSource(children({ isDragging })) : children({ isDragging })
    );
    return <Source />
}

然后您可以像这样使用它:

<Draggable type='FOO' source={{id: 1}} collector = {() => ({})} >
    {({isDragging}) => (
        <div>
            {isDragging ? <p>Dragging...</p> : <p>Not Dragging...</p>}
        </div>
    )}
</Draggable>

Edit 54lwm407n4