Delete an element by key from Array

2020-05-03 11:50发布

I used library react-sortable-hoc for drag and drop element, but the library documentation does not have any actions for delete items. I want to delete, drag and drop item when click on close button. Which method is right for removing elements by key from object?

React

const SortableItem = SortableElement(({ value }: { value: string }, onRemove: any) =>
    <div className="dragItems" style={{ background: 'gray' }}>
        <img src={value} alt="" />
        <button className="dragCloseBtn" onClick={() => onRemove(any)} />
    </div>

);

const SortableList = SortableContainer(({ items }: { items: string[] }) => {
    return (
        <div className="dragAndDrop">
            {items.map((value, index) => (
                <SortableItem key={'item-${index}'} index={index} value={value} />
            ))}
        </div>
    );
});

constructor(props: any) {
    super(props);
    this.state = {
        items: [
            { 
                "id": 0, 
                "link": "https://via.placeholder.com/150"
            },
            { 
                "id": 1, 
                "link": "https://via.placeholder.com/150"
            }
        ],
    };
}

public onSortEnd = ({ oldIndex, newIndex }: { oldIndex: number, newIndex: number }) => {
    this.setState({
        items: arrayMove(this.state.items, oldIndex, newIndex),
    });
};

public onRemove(e: { target: { value: any; }; }) {
    const array = [...this.state.items]; 
    const index = array.indexOf(e.target.value)
    if (index !== -1) {
        array.splice(index, 1);
        this.setState({items: array});
    }
}

<SortableList items={this.state.items}
              onSortEnd={this.onSortEnd}
              lockAxis="xy"
              axis="xy" />

2条回答
趁早两清
2楼-- · 2020-05-03 12:21

UPDATED:

Hi there, I figured out what went wrong and made a successful remove event on your application.

Everything is illustrated with comments at this codesandbox.

=========

I modified this one, it should do the required using Array's filter method.

public onRemove(e: { target: { value: any; }; }) {
    let array = [...this.state.items];
    const intId = parseInt(e.target.value, 10);
    array = array.filter(item => item.id !== intId);
    this.setState({items: array});
}
查看更多
家丑人穷心不美
3楼-- · 2020-05-03 12:24

So there were few problems in your code! You seemed to be confuse how react works with passing down props. You have to pass down the method required for remove. And you should bind it inside the class that you will be calling it.

  • onRemove should be bound to current context
  • onRemove should be passed down across the component tree
  • Check my //[NOTE]====> comments for additional explanation
  • Working code sandbox is here
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
  arrayMove,
  SortableContainer,
  SortableElement
} from "react-sortable-hoc";


//[NOTE]====>value contains the relevent object containing the callback. Onclick call it with the relevant id
const SortableItem = SortableElement(
  ({ value }: { value: any }, onRemove: any) => (
    <div className="dragItems" style={{ background: "gray", margin: "20px" }}>
      <img src={value.link} alt="" />
      <button className="dragCloseBtn" onClick={() => value.onRemove(value.id)}>
        {" "}
        X{" "}
      </button>
    </div>
  )
);

const SortableList = SortableContainer(({ items }: { items: string[] }) => {
  return (
    <div className="dragAndDrop">
      {items.map((value, index) => (
        <SortableItem key={`item-${index}`} index={index} value={value} />
      ))}
    </div>
  );
});

class SortableComponent extends React.Component<{}, { items: string[] }> {
  constructor(props: {}) {
    super(props);

    //[NOTE]====>Send the callback on each element bound to the current context
    //This is like telling the function from where exactly the function will be called
    this.state = {
      items: [
        {
          id: 0,
          link: "https://via.placeholder.com/150",
          onRemove: this.onRemove.bind(this)
        },
        {
          id: 1,
          link: "https://via.placeholder.com/150",
          onRemove: this.onRemove.bind(this)
        }
      ]
    };
  }
  public render() {
    return <SortableList items={this.state.items} onSortEnd={this.onSortEnd} />;
  }
  public onSortEnd = ({
    oldIndex,
    newIndex
  }: {
    oldIndex: number;
    newIndex: number;
  }) => {
    this.setState({
      items: arrayMove(this.state.items, oldIndex, newIndex)
    });
  };

  //[NOTE]====>Use the id to filter out and set the new set of items
  public onRemove(id) {
    console.log(id);
    let array = [...this.state.items];
    const intId = parseInt(id, 10);
    array = array.filter((item: any) => item.id !== intId);
    this.setState({ items: array });
  }
}

ReactDOM.render(<SortableComponent />, document.getElementById("root"));
查看更多
登录 后发表回答