Gurnzbot
Gurnzbot

Reputation: 4132

React DnD with HOC draggable elements throw Cannot set property 'props' of undefined error

I am trying to use React DnD with a number of different draggable elements (different shapes, etc). They are all basically the same and have the same behaviour, so I figured using HOCs would be a good idea.

I have the following HOC that is a draggable component via React DnD:

import React, { Component } from "react";
import { DragSource } from "react-dnd";

// Components
import ItemTypes from "./ItemTypes";

/**
 * Implements the drag source contract.
 */
const itemSource = {
    beginDrag(props) {
        return {};
    }
};

/**
 * Specifies the props to inject into your component.
 */
function collect(connect, monitor) {
    return {
        connectDragSource: connect.dragSource(),
        isDragging: monitor.isDragging()
    };
}

const DragItem = WrappedComponent => {
    return class extends Component {
        render() {
            const { isDragging, connectDragSource } = this.props;
            return connectDragSource(<WrappedComponent isDragging={isDragging} {...this.props} />);
        }
    };
};

export default DragSource(ItemTypes.BOX, itemSource, collect)(DragItem);

I then have the base element that should implement the draggable HOC:

import React, { Component } from "react";
import DragItem from "../DragItem";

class Box extends Component {
    render() {
        return (
            <div
                style={{
                    height: "50px",
                    width: "50px",
                    background: "red"
                }}
            />
        );
    }
}

export default DragItem(Box);

And here is the DnD context that ties them both together:

import React, { Component } from "react";
import { DragDropContext } from "react-dnd";
import HTML5Backend from "react-dnd-html5-backend";

// Components
import DropContainer from "./dragNDropUploader/DropContainer";
import Box from "./dragNDropUploader/types/Box";

class UploadTest extends Component {
    render() {
        return (
            <div className="body_container padded_top padded_bottom">
                <DropContainer />
                <Box />
            </div>
        );
    }
}

export default DragDropContext(HTML5Backend)(UploadTest);

I get the following in the dev tools console: react.development.js:233 Uncaught TypeError: Cannot set property 'props' of undefined

I'm not entirely sure what I'm doing wrong. If I remove the DnD stuff from the DragItem HOC, things display as expected (however not draggable of course). But if I try to implement DnD as I have, it breaks and dies.

Please school me :)

Upvotes: 4

Views: 1579

Answers (1)

HoldOffHunger
HoldOffHunger

Reputation: 20891

This is how I would define the render() of a draggable component...

return (
    <div
        onClick={(e) => this.handleClick(e)}
        onDragStart={(e) => this.handleDragStart(e)}
        onDrop={(e) => this.handleDragDrop(e)}
        onDragEnter={(e) => this.handleDragEnter(e)}
        onDragOver={(e) => this.handleDragOver(e)}
        onDragLeave={(e) => this.handleDragLeave(e)}
        draggable={true}
    >Draggable Div</div>
);

For the ReactJS handler for all of these, have this:

handleDragEnter(e) {
    e.preventDefault();
    e.stopPropagation();
    return false;
}

Except for the handleDragStart(e) handler, which doesn't cancel the event or return false. You can put any kind of logic you want in any of the handlers.

This "overkill" is largely because of how various browsers handle drag and drop, for instance, if you drag element A onto element B in Chrome, nothing may happen, but in Firefox, it will try to open element A as though it were a file.

More than half of the packages I've tried at npm, etc., simply do not work. One must treat an NPM package as though they had downloaded a SourceForge project -- there is almost a 100% guarantee against all functionality working perfectly. So, I'm not sure what's wrong with the particular HOC you downloaded, but I hope these 10 lines of code are just as easy to understand as the 3 pages you posted.

Upvotes: 0

Related Questions