3

我无法让 react-dnd 工作。具体来说,虽然我可以确认正确检测到拖动,但我的可放置目标没有检测到悬停或放置事件。我一直在遵循http://survivejs.com/react/implementing-kanban/drag-and-drop/上的示例来创建可拖动项目。我尝试使用相同示例和官方 repo中的官方示例的组合来创建 DropTarget 以接受可拖动。但是,我的 DropTarget 没有表明它正在检测可拖动对象。我下面的代码有多个调试器语句来指示是否正在到达代码,但它们都不是。我怀疑compose最后的电话可能是问题所在,但我在这里遵循 Dan Abramov 的示例. 只是为了增加问题,Chrome 开发工具中的 React 检查器让我在itemType拖动项目时看到状态变量的变化。但是,thecanDropisOverstate 变量都保持为假。我将不胜感激任何帮助以使其正常工作。

import { findDOMNode } from 'react-dom';
import React, { Component } from 'react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Paper from 'material-ui/Paper';
import FaDelete from 'react-icons/lib/fa/trash-o';
import RaisedButton from 'material-ui/RaisedButton';
import FaEdit from 'react-icons/lib/fa/star';
import actions from '../actions/actions';
import TextField from 'material-ui/TextField';
import { connect } from 'react-redux';
//import EmojiPickerPopup from './EmojiPickerPopup';
import RenderIf from 'render-if';
import globals from '../globals';
import { DropTarget } from 'react-dnd';
import { compose } from 'redux';

const locationItemContainer = {
    display: 'flex',
    flexDirection: 'column',
    backgroundColor: 'lightgoldenrodyellow',
    border: '1px solid Moccasin',
    width: "33%",
    maxHeight: "15em"
}

const controlsContainer = {
    display: 'flex',
    flexDirection: 'row',
    justifyContent: 'space-around',
    width: "100%"
}

const paperStyle = {
    padding: '8px 4px',
    display: 'flex',
    flexDirection: "column",
    alignItems: 'center',
    justifyContent: 'center',
    width: "100%",
    height: "100%"
};

class LocationItemComponent extends Component {
    constructor(props, context) {
        super(props, context);
        this.state = {
            locationMarkers: []
        }
    }

    componentWillReceiveProps(nextProps) {
        if (!this.props.isOver && nextProps.isOver) {
            // You can use this as enter handler
            debugger
        }

        if (this.props.isOver && !nextProps.isOver) {
            // You can use this as leave handler
            debugger
        }

        if (this.props.isOverCurrent && !nextProps.isOverCurrent) {
            // You can be more specific and track enter/leave
            // shallowly, not including nested targets
            debugger
        }
    }

    nameChanged = (id, event, value) => {
        this.props.dispatch(actions.storyMapActions.updateMarkerName(value, id));
    }
    deleteMarker = (id) => {
        this.props.dispatch(actions.storyMapActions.deleteMarker(id));
    }
    showEmojiPicker = (id, event) => {
        this.props.dispatch(actions.modalsActions.showEmojiPicker(id, event.currentTarget))
    }
    render() {
        const { isOver, canDrop, connectDropTarget } = this.props;
        if (isOver) {
            console.log("is over");
        }
        return connectDropTarget(
            <div style={locationItemContainer}>
                <MuiThemeProvider>
                    <Paper zDepth={5}
                        style={paperStyle}
                        rounded={false}>
                        <TextField
                            id="markerName"
                            hintText="marker Name"
                            onChange={this.nameChanged.bind(this, this.props.marker.id)}
                            value={this.props.marker.name}
                            underlineFocusStyle={{ color: globals.textUnderlineColor }}
                            />
                        <div style={controlsContainer}>
                            <RaisedButton
                                icon={<FaEdit />}
                                primary={true}
                                onClick={this.showEmojiPicker.bind(this, this.props.marker.id)} />
                            <RaisedButton
                                icon={<FaDelete />}
                                secondary={true}
                                onClick={this.deleteMarker.bind(this, this.props.marker.id)} />
                        </div>
                    </Paper>
                </MuiThemeProvider>
            </div>
        );
    }
}
const mapStateToProps = (state) => {
    return Object.assign({}, { state: state });
}

const locationTarget = {
    canDrop(props, monitor) {
        debugger;
        // You can disallow drop based on props or item
        const item = monitor.getItem();
        return true;
    },

    hover(props, monitor, component) {
        debugger;
        // This is fired very often and lets you perform side effects
        // in response to the hover. You can't handle enter and leave
        // here—if you need them, put monitor.isOver() into collect() so you
        // can just use componentWillReceiveProps() to handle enter/leave.

        // You can access the coordinates if you need them
        const clientOffset = monitor.getClientOffset();
        const componentRect = findDOMNode(component).getBoundingClientRect();

        // You can check whether we're over a nested drop target
        const isJustOverThisOne = monitor.isOver({ shallow: true });

        // You will receive hover() even for items for which canDrop() is false
        const canDrop = monitor.canDrop();
    },

    drop(props, monitor, component) {
        debugger;
        if (monitor.didDrop()) {
            // If you want, you can check whether some nested
            // target already handled drop
            debugger
            return;
        }
        // Obtain the dragged item
        const item = monitor.getItem();

        // You can do something with it
        //ChessActions.movePiece(item.fromPosition, props.position);

        // You can also do nothing and return a drop result,
        // which will be available as monitor.getDropResult()
        // in the drag source's endDrag() method
        return { moved: true };
    }
};

const collect = (connect, monitor) => {
    return {
        connectDropTarget: connect.dropTarget(),
        isOver: monitor.isOver(),
        canDrop: monitor.canDrop(),
        itemType: monitor.getItemType()
    };
}

export default compose(
    connect(mapStateToProps),
    DropTarget(globals.itemTypes.LOCATION_ITEM, locationTarget, collect)

)(LocationItemComponent);
4

0 回答 0