使用 ReactJs 和 react-dnd 拖放可排序列表的问题

Posted

技术标签:

【中文标题】使用 ReactJs 和 react-dnd 拖放可排序列表的问题【英文标题】:Trouble with drag-and-drop sortable list using ReactJs and react-dnd 【发布时间】:2015-06-23 10:43:55 【问题描述】:

使用ReactJs 和react-dnd

我希望用户能够对表单字段进行排序(又名properties

我为simple sort demo 中的卡片设置了与source code 几乎相同的代码。没有控制台警告或错误,我不知道为什么这不起作用。我不能拖放任何东西。

它的样子:

代码:

App.js

import EditForm from './Forms/EditForm.js';

var id = $('#form').data('id');
var source = `/api/forms/$id?include=type,properties.type`;

React.render(
    <EditForm source=source />,
    document.getElementById('form')
);

EditForm.js

import React from 'react/addons';
import update from 'react/lib/update';
import Property from './Property.js';

var EditForm = React.createClass(

    mixins: [ React.addons.LinkedStateMixin ],

    getInitialState: function() 
        return 
            id: null,
            name: null,
            slug: null,
            properties: []
        
    ,

    componentDidMount: function() 
        this.getFormFromServer();
    ,

    getFormFromServer: function () 
        $.get(this.props.source, (result) => 
            if (this.isMounted()) 
                this.setState(
                    id: result.id,
                    name: result.name,
                    slug: result.slug,
                    properties: result.properties.data
                );
            
        );
    ,

    moveProperty: function(id, afterId) 
        const  properties  = this.state;

        const property = properties.filter(p => p.id === id)[0];
        const afterProperty = properties.filter(p => p.id === afterId)[0];
        const propertyIndex = properties.indexOf(property);
        const afterIndex = properties.indexOf(afterProperty);

        this.setState(update(this.state, 
            properties: 
                $splice: [
                    [propertyIndex, 1],
                    [afterIndex, 0, property]
                ]
            
        ));
    ,

    render: function() 
        const  properties  = this.state;

        var propertiesList = properties.map((property, i) => 
            return (
                <Property
                    key=property.id
                    id=property.id
                    type=property.type.name
                    name=property.name
                    moveProperty=this.moveProperty />
            );
        );

        return (
            <div>
                <h1>Form</h1>
                <form>
                    <div className="form-group">
                        <label>Name:</label>
                        <input type="text" name="name" valueLink=this.linkState('name') className="form-control" />
                    </div>
                    <div className="form-group">
                        <label>Properties:</label>
                        <div className="list-group properties-list">
                            propertiesList
                        </div>
                    </div>
                </form>
            </div>
        );
    

);

export default EditForm;

Property.js

import React,  PropTypes  from 'react/addons';
import  DragDropMixin  from 'react-dnd';
import ItemTypes from './ItemTypes';

const dragSource = 
    beginDrag(component) 
        return 
            item: 
                id: component.props.id
            
        ;
    
;

const dropTarget = 
    over(component, item) 
        component.props.moveProperty(item.id, component.props.id);
    
;

var Property = React.createClass(

    mixins: [ React.addons.LinkedStateMixin, DragDropMixin ],

    propTypes: 
        id: PropTypes.any.isRequired,
        type: PropTypes.string.isRequired,
        name: PropTypes.string.isRequired,
        moveProperty: PropTypes.func.isRequired
    ,

    statics: 
        configureDragDrop(register) 
            register(ItemTypes.PROPERTY, 
                dragSource,
                dropTarget
            );
        
    ,

    render: function () 
        const  type  = this.props;
        const  name  = this.props;
        const  isDragging  = this.getDragState(ItemTypes.PROPERTY);
        const opacity = isDragging ? 0 : 1;

        return (
            <a  className="list-group-item"
                ...this.dragSourceFor(ItemTypes.PROPERTY)
                ...this.dropTargetFor(ItemTypes.PROPERTY)>
                type: name
            </a>
        );
    
);

export default Property;

ItemTypes.js

module.exports = 
    PROPERTY: 'property'
;

如果有人可以提供帮助,我将不胜感激。我实际上花了多少时间试图弄清楚这一点,这有点令人难过。

参考链接:

My code on github Demo example Demo source on github

【问题讨论】:

您介意将未缩小的代码添加到 JSBin 吗?让您更轻松地玩耍并查看正在发生的事情。 @AndersEkdahl 我试过了,但它没有出现......可能是因为 ES6 的东西或什么,我不确定......jsbin.com/vucuji/1/edit?html,js,output 编辑:呃,看起来我的 html 消失了 - _-;; 这里有一个小提琴。我让它渲染,但只有当 JSX 已经转换时:jsfiddle.net/fungku/u88kxbvk 那个代码块相当大。你能用 JSBin 代替吗?它提供 JSX 支持。请只包含查看问题所需的代码,将库添加为脚本标签。 在我什至不想知道拔了多少个小时的头发之后,是fixed... 【参考方案1】:

在花了一天多的时间试图让拖放功能正常工作后,我用one single line of code 修复了它。

import React from 'react/addons';

如果没有它,它是如何编译和渲染的,我什至不知道。

【讨论】:

以上是关于使用 ReactJs 和 react-dnd 拖放可排序列表的问题的主要内容,如果未能解决你的问题,请参考以下文章

react-dnd 中的动画

使用 react-dnd 和 useDrag 和 useDrop 进行测试

react-dnd 使用

如何将项目拖放到 react-dnd 中的空白部分?

为啥拖放 ReactJS 时光标图标没有改变?

reactjs - redux 表单和材质 ui 框架 - 拖放文件上传器