1

I don't know why this is not working. When I run removeFromCart, it works but it doesn't work in updateCount . Please help me fix this.

 updateCount = (id,increment) => { const cartItems = this.state.cart; if((this.findItem(cartItems, id).count == 1 && increment < 0)) this.removeFromCart(id); else{ this.findItem(cartItems, id).count += increment; } this.setState({ cart: cartItems }); } removeFromCart = id=>{ const cartItems = this.state.cart.filter(el=> el.id !== id); this.setState({ cart: cartItems }); } findItem = (arr,id)=> { return arr.find(e=> e.id === id); } 

You can find the full source on Github

7
  • What's the error that you're seeing? Commented Oct 3, 2020 at 4:02
  • I am not getting any error. Commented Oct 3, 2020 at 4:04
  • Can you be more specific about what "it" is that is or isn't working? What does findItem do? Looks like you is mutating some object. Commented Oct 3, 2020 at 4:09
  • 'it' is removeFromCart. findItem helps to get the object whose id is equal to id. Commented Oct 3, 2020 at 4:10
  • 1
    Please update the locale file of your code Commented Oct 3, 2020 at 4:16

1 Answer 1

1

Took a bit of time poring over your code, not much was obviously wrong (other than state mutations), eventually I just cloned your repo into a codesandbox and debugged.

Issue

The issue is the state update from updateCount and another from removeFromCart. The condition this.findItem(cartItems, id).count == 1 && increment < 0 is true and this.removeFromCart is called, the cart item is found and a state update it enqueued. Execution returns to updateCount and a second state update is enqueued. The second update overwrites the first with the cartItems (state) enclosed in function scope.

updateCount = (id, increment) => { const cartItems = this.state.cart; if (this.findItem(cartItems, id).count == 1 && increment < 0) this.removeFromCart(id); else { this.findItem(cartItems, id).count += increment; } this.setState({ cart: cartItems // <-- State update #2 }); }; removeFromCart = (id) => { const cartItems = this.state.cart.filter((el) => el.id !== id); this.setState({ cart: cartItems // <-- State update #1 }); }; 

Solution

When removing an item from the cart only enqueue a single state update. Tuck the second update into the logic branch that is updating it.

updateCount = (id, increment) => { const cartItems = this.state.cart; if (this.findItem(cartItems, id).count == 1 && increment < 0) this.removeFromCart(id); else { this.findItem(cartItems, id).count += increment; this.setState({ cart: cartItems }); } }; 

At this point your code appears to function correctly, but I should note that this.findItem(cartItems, id).count += increment; is technically a state mutation. It's obscured by the fact that a line later you at least copy into a new state object. You should always avoid state mutations. I suggest the following edit to map to a new cart array when updating item counts. Also use === instead of == for equality comparisons unless you have a good reason to.

updateCount = (id, increment) => { const cartItems = this.state.cart; if (this.findItem(cartItems, id).count === 1 && increment < 0) this.removeFromCart(id); else { this.setState({ cart: cartItems.map((item) => item.id === id ? { ...item, count: item.count + increment } : item ) }); } }; 

Edit react-function-not-executing

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.