从react-beautiful-dnd水平列表中删除单个项目

时间:2018-05-30 20:10:57

标签: reactjs drag-and-drop react-redux

我有react-beautiful-dnd水平多个列表(每行6个,每行相同的项目),每个列表中有相同的项目。 我想从每个列表中删除单个选定的项目,但只有一个带有onClick的按钮组件会在呈现列表本身时触发onClick。如何配置列表,以便在单击关闭/删除(x)按钮时从该列表中删除单个项目?

下面是我的代码,

    import React, { Component } from 'react';
    import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
    import {Button, Icon} from 'semantic-ui-react'

    // a little function to help us with reordering the result
    const reorder = (list, startIndex, endIndex) => {
    const result = Array.from(list);
    const [removed] = result.splice(startIndex, 1);
    result.splice(endIndex, 0, removed);
    return result;
    };

    const grid = 12;
    const getItemStyle = (isDragging, draggableStyle) => ({
    // some basic styles to make the items look a bit nicer
    userSelect: 'none',
    padding: grid / 2,
    margin: `0 ${grid}px 0 0`,

    // change background colour if dragging
    background: isDragging ? 'lightgreen' : 'lightgray',

    // styles we need to apply on draggables
    ...draggableStyle,
    });

    const getListStyle = isDraggingOver => ({
    background: isDraggingOver ? 'lightblue' : 'white',
    display: 'flex',
    padding: grid,
    overflow: 'auto',
    });

    class DragAndDrop extends Component {
    constructor(props) {
        super(props);
        this.state = {
        items: this.props.uniqueEntries
        };
        this.onDragEnd = this.onDragEnd.bind(this)
        this.removeSubject = this.removeSubject.bind(this)
    }

    onDragEnd(result) {
        // dropped outside the list
        if (!result.destination) {
        return;
        }
        const items = reorder(
        this.state.items,
        result.source.index,
        result.destination.index
        );

        this.setState({
        items,
        });
    }

    componentWillReceiveProps(newProps){
        this.setState({
        items : newProps.uniqueEntries
        })

    }

    removeItem = (index) => {
        this.state.items.splice(index, 1)
    }

    render() {
        return (
        <DragDropContext onDragEnd={this.onDragEnd}>
            <Droppable droppableId="droppable" direction="horizontal">
            {(provided, snapshot) => (
                <div
                ref={provided.innerRef}
                style={getListStyle(snapshot.isDraggingOver)}
                {...provided.droppableProps}
                >
                {this.state.items.map((item, index) => (
                    <Draggable key={item.Id} draggableId={item.Id} 
                   index={index}>
                    {(provided, snapshot) => (
                        <div
                        ref={provided.innerRef}
                        {...provided.draggableProps}
                        {...provided.dragHandleProps}
                        style={getItemStyle(
                            snapshot.isDragging,
                            provided.draggableProps.style
                        )}
                        >
                        <Button icon size='mini'
                        style={{backgroundColor : 'lightgray' ,padding: 
                        '0', float: 'right'}}
                        onClick = {this.removeItem(index)}>
                        <Icon name='close' />
                        </Button>
                        {item.name}
                        </div>
                    )}
                    </Draggable>
                ))}
                {provided.placeholder}
                </div>
            )}
            </Droppable>
        </DragDropContext>
        );
    }
   }

    export default DragAndDrop

2 个答案:

答案 0 :(得分:1)

我发现为什么它在渲染时触发,而不是传递我正在启动它的函数,所以通过它被调用的循环。然后我做了这个,它工作。这可能会帮助那些可能遇到类似问题的人。

<Button icon size='mini'
                  style={{backgroundColor : 'lightgray' ,padding: '0', 
  float: 'right', marginLeft:'15px'}}
                  onClick = {() => this.removeItem(index)}>
                  <Icon name='close' />
                </Button>

答案 1 :(得分:1)

此错误的注释,可能会影响您和未来的观众。 ?

你不应该直接改变状态。它会产生一些副作用或根本没有。

我还建议您生成唯一 ID,因为如果您创建更多列表,它也会有一些意想不到的结果,即使 react-beautiful-dnd 不会注意到。

如果要更新或删除状态数据,请使用 setState()。首先使用副本修改现有数据。然后分配新值。

removeItem(index) {

// do magic here to filter out the unwanted element

// Update via 'setState'
        this.setState({
            items : newModifiedItems
        })
}

以我下面的试用方法为例:

removeItem(e) {
        e.preventDefault();

        // give your single list a className so you can select them all
        const sourceList = document.querySelectorAll(".list-name");

        const arrList= Array.from(sourceList);

        // make shallow copy of your state data
        const newItems = Array.from(this.state.items);

        // Find index element from whole list Arr by traversing the DOM
        const removeItemIndex = arrList.indexOf(e.target.parentElement);

        // Remove it
        newItems.splice(removeItemIndex, 1);

        this.setState({
            items: newItems 
        })

    }