首页 > 解决方案 > 反应元素类型无效

问题描述

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

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 />;
  }
}

我不断收到此错误:

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

标签: javascriptreactjsreact-dnd

解决方案


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

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

你可以做些什么来将 HOC 转换为一个将渲染道具作为唯一子元素的组件:

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>

编辑 54lwm407n4


推荐阅读