1

Right now i need to increment/decrement a property value of state's array of objects. I have tried throwing everything that came to my mind to setState. At times it didnt throw any errors, but wasn't updating the value either Right now i get error message:

this.state.products[key] is undefined

constructor(props) {

    super(props)

    var products = [
        { name: "Motorhead glasses", price: 300, amount: 1 },
        { name: "Judaspriest glasses", price: 499, amount: 1 }
    ]

    this.state = { products: products }
    this.handleMinus = this.handleMinus.bind(this)

}


handleMinus(key) {
    var stateCopy = Object.assign({}, this.state);
    stateCopy.products = stateCopy.products.slice();
    stateCopy.products[key] = Object.assign({}, stateCopy.products[key]);
    stateCopy.products[key].amount += 1;
    this.setState({ [this.state.products[key].amount]: stateCopy });
    console.log(this)
}
EDGECRUSHER
  • 83
  • 1
  • 10

3 Answers3

2

You you clone a state object, you can modify it directly and setback to state

handleMinus(key) {
    var stateCopy = [...this.state.products];   /Create a copy of products array using spread operator syntax.
    stateCopy[key].amount += 1;
    this.setState({products : stateCopy });

}

If you wanna know what [...this.state.products] mean check this answer: What is the meaning of this syntax "{...x}" in Reactjs

Community
  • 1
  • 1
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
0

Use this (check the comments):

handleMinus(key) {
    var stateCopy = this.state.products.slice();        //create a copy of products array
    stateCopy[key] = Object.assign({}, stateCopy[key])  //create a copy of object at that key
    stateCopy[key].amount += 1;                         //modify the value
    this.setState({products : stateCopy });             //update the state variable
}

Your code will also work with a small change, change the way you are using setState to update the state value, use this:

handleMinus(key) {
    var stateCopy = Object.assign({}, this.state);
    stateCopy.products = stateCopy.products.slice();
    stateCopy.products[key] = Object.assign({}, stateCopy.products[key]);
    stateCopy.products[key].amount += 1;
    this.setState(stateCopy);   //use this
}
Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
0

You’re making unnecessary shallow copies of your state.

handleMinus(key) {
  const product = this.state.products[key];

  this.setState({
    products: [
      ...this.state.products,

      [key]: Object.assign({}, product, {
        amount: product.amount + 1
      })
    ]
  })
}
Bertrand Marron
  • 21,501
  • 8
  • 58
  • 94