简体   繁体   中英

Remove selected item from array

I have a simple form, where I would like to remove the selected item on remove button click. I'm partially removing the desired item, but if I remove the middle item, it also removes the last item. If I remove the first item, it removes the entire array.

Live example here

code here:

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      data: ["Saab", "Volvo", "BMW"],
      editMode: false,
      rulesTerm: ""
    };
  }

    handleInput = e => {
    let value = e.target.value;
    let name = e.target.name;
    console.log(name);
    console.log(value);

    this.setState(prevState => ({
      data: {
        ...prevState.data,
        [name]: value
      }
    }));
  };

  handleFormSubmit = e => {
    e.preventDefault();

    const { data } = this.state;
    console.log(data);
  };

  removeRule = (e, index) => {
    e.preventDefault();

    const { data } = this.state;
    console.log("removed", data.splice(index));

    this.setState({
      data: data,
      rulesTerm: ""
    });
  };

  render() {
     return (
       <div className="App">
        <div>
          {!this.state.editMode ? (
            <button onClick={() => this.setState({ editMode: true })}>
              edit
            </button>
          ) : (
            <div>
              <button onClick={() => this.setState({ editMode: false })}>
                cancel
               </button>
              <button onClick={this.handleFormSubmit}>submit</button>
            </div>
           )}
        </div>

        <React.Fragment>
          {this.state.data.map((rule, index) =>
            this.state.editMode ? (
              <form onSubmit={this.handleFormSubmit}>
                <React.Fragment>
                  <input
                    onChange={this.handleInput}
                    type="text"
                    placeholder="Cars"
                    name={rule}
                    defaultValue={rule}
                    key={index}
                  />
                  <button onClick={event => this.removeRule(event, index)}>
                    Remover
                  </button>
                </React.Fragment>
              </form>
            ) : (
              <p key={rule}> - {rule} </p>
            )
          )}
        </React.Fragment>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Any help? Thank you!

When using splice , you need to pass in the number of elements to delete.

If deleteCount is omitted, or if its value is equal to or larger than array.length - start (that is, if it is equal to or greater than the number of elements left in the array, starting at start), then all of the elements from start through the end of the array will be deleted.

One solution would be to convert your deleting function into a curried function, which will first receive the index when called once, and then the event.

You can filter out your element using the callback version of setState and filtering out the element with the same index :

removeRule = index => event => {
    this.setState(prev => ({
        data: prev.data.filter((el, i) => i !== index),
        rulesTerm: ""
    }));
};

You could also indicate your splice method that it only requires to remove a single element :

removeRule = index => event => {
    this.setState(prev => ({
        data: prev.data.splice(index, 1),
        rulesTerm: ""
    }));
};

Your function binding in the JSX will now look like the following :

<button onClick={this.removeRule(index)}>
    Remover
</button>

In your case I would use a filter, and pass the rule as an argument:

 <React.Fragment>
          {this.state.data.map((rule, index) =>
            this.state.editMode ? (
              <form onSubmit={this.handleFormSubmit}>
                <React.Fragment>
                  <input
                    onChange={this.handleInput}
                    type="text"
                    placeholder="Cars"
                    name={rule}
                    defaultValue={rule}
                    key={index}
                  />
                  <button onClick={event => this.removeRule(event, rule)}>
                    Remover
                  </button>
                </React.Fragment>
              </form>
            ) : (
              <p key={rule}> - {rule} </p>
            )
          )}
        </React.Fragment>

Than in your removeRule function:

removeRule = (e, rule) => {
    e.preventDefault();

    const { data } = this.state;
    const newData = data.filter(item => item !== rule);
    console.log("removed");

    this.setState({
      data: newData,
      rulesTerm: ""
    });
  };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM