Removing element from array in component state

前端 未结 10 2004
感动是毒
感动是毒 2020-11-28 01:31

I am trying to find the best way to remove an element from an array in the state of a component. Since I should not modify the this.state variable directly, is

相关标签:
10条回答
  • 2020-11-28 02:05

    Here is a simple way to do it:

    removeFunction(key){
      const data = {...this.state.data}; //Duplicate state.
      delete data[key];                  //remove Item form stateCopy.
      this.setState({data});             //Set state as the modify one.
    }
    

    Hope it Helps!!!

    0 讨论(0)
  • 2020-11-28 02:07

    The cleanest way to do this that I've seen is with filter:

    removeItem(index) {
      this.setState({
        data: this.state.data.filter((_, i) => i !== index)
      });
    }
    
    0 讨论(0)
  • 2020-11-28 02:09

    I believe referencing this.state inside of setState() is discouraged (State Updates May Be Asynchronous).

    The docs recommend using setState() with a callback function so that prevState is passed in at runtime when the update occurs. So this is how it would look:

    Using Array.prototype.filter without ES6

    removeItem : function(index) {
      this.setState(function(prevState){
        return { data : prevState.data.filter(function(val, i) {
          return i !== index;
        })};
      });
    }
    

    Using Array.prototype.filter with ES6 Arrow Functions

    removeItem(index) {
      this.setState((prevState) => ({
        data: prevState.data.filter((_, i) => i !== index)
      }));
    }
    

    Using immutability-helper

    import update from 'immutability-helper'
    ...
    removeItem(index) {
      this.setState((prevState) => ({
        data: update(prevState.data, {$splice: [[index, 1]]})
      }))
    }
    

    Using Spread

    function removeItem(index) {
      this.setState((prevState) => ({
        data: [...prevState.data.slice(0,index), ...prevState.data.slice(index+1)]
      }))
    }
    

    Note that in each instance, regardless of the technique used, this.setState() is passed a callback, not an object reference to the old this.state;

    0 讨论(0)
  • 2020-11-28 02:15

    I want to chime in here even though this question has already been answered correctly by @pscl in case anyone else runs into the same issue I did. Out of the 4 methods give I chose to use the es6 syntax with arrow functions due to it's conciseness and lack of dependence on external libraries:

    Using Array.prototype.filter with ES6 Arrow Functions

    removeItem(index) {
      this.setState((prevState) => ({
        data: prevState.data.filter((_, i) => i != index)
      }));
    }
    

    As you can see I made a slight modification to ignore the type of index (!== to !=) because in my case I was retrieving the index from a string field.

    Another helpful point if you're seeing weird behavior when removing an element on the client side is to NEVER use the index of an array as the key for the element:

    // bad
    {content.map((content, index) =>
      <p key={index}>{content.Content}</p>
    )}
    

    When React diffs with the virtual DOM on a change, it will look at the keys to determine what has changed. So if you're using indices and there is one less in the array, it will remove the last one. Instead, use the id's of the content as keys, like this.

    // good
    {content.map(content =>
      <p key={content.id}>{content.Content}</p>
    )}
    

    The above is an excerpt from this answer from a related post.

    Happy Coding Everyone!

    0 讨论(0)
提交回复
热议问题