score:5

Accepted answer

am i not following best practices here?

nope. the problem is that you are not working with temporary variables, like you might believe, but are mutating deleteditems directly. basically:

const itemsstate = this.state.items;
const deleteditemsstate = this.state.deleteditems;

these lines do not create a copy of the respective state variables, but instead only creates a reference to them.

so when you do

deleteditemsstate.push(itemtobedeleted);

you are mutating the state directly! which is a no-no, as you probably already know.

why does this happen?

to understand this, you must understand that assignments between primitive and compound values work differently.

for example:

var x = y;

x will copy the value of y if y is a string, number, boolean, null or undefined. however, if it's an object, array or a function x will store its reference.


solution:

what you need to do is to create a shallow copy of them. like so:

const itemsstate = this.state.items.slice();
const deleteditemsstate = this.state.deleteditems.slice();

this will make itemsstate and deleteditemsstate separate variables from this.state.item and this.state.deleteditems respectively.


demo:

class myapp extends react.component {
  constructor() {
    super();
    this.state = {
      items: ['item 1', 'item 2', 'item 3'],
      deleteditems: ['item 4', 'item 5']
    };
  }

  removeitem = (number) => {
    const itemsstate = this.state.items;
    const deleteditemsstate = this.state.deleteditems;

    const itemtobedeleted = itemsstate[number];
    deleteditemsstate.push(itemtobedeleted);

    itemsstate.splice(number, 1);
    this.setstate({
      items: itemsstate
    }, () => {
      console.log(this.state);
    });
  }

  render() {
    return (
      <div>
        items:
        <ul>
          {this.state.items.map((item, i) => <li>{item} <button onclick={this.removeitem.bind(this, i)}>remove</button></li>)}
        </ul>
        deleted items:
         <ul>
          {this.state.deleteditems.map(item => <li>{item}</li>)}
        </ul>
      </div>
    );
  }
}

reactdom.render( < myapp / > , document.getelementbyid("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

score:0

this is not the correct way to handle state changes in your app.

for instance, this line

const itemsstate = this.state.items;

it creates a variable itemsstate which points to this.state.items. so any changes you make to itemsstate, it will get changed in your state.items as well. this mutates your data.

the best practice is to use a library such as immutability-helper to make state updates or either clone your state object into variables and then perform mutations on them. and after you are done, finally update the state using setstate().

here is a code snippet to explain how you can clone using object.assign(). this won't change your original state variables as you can see in the snippet.

var state = {
    items: ['item 1', 'item 2', 'item 3'],
    deleteditems: ['item 4', 'item 5']
  };
  
function removeitem(number) {
    const itemsstate = object.assign([], this.state.items);
    const deleteditemsstate = object.assign([], this.state.deleteditems);

    const itemtobedeleted = itemsstate[number];
    deleteditemsstate.push(itemtobedeleted);

    itemsstate.splice(number, 1);
    //this.setstate({ items: itemsstate });
    
    console.log(state);
  }
  
removeitem(1);


Related Query

More Query from same tag