data_pirate96
data_pirate96

Reputation: 13

Unable to update the state of a react component

I am a novice full stack developer working on a basic shopping cart front-end task.

My cartItems array which is is a part of the state is not updating when I click on addtoCart. The addtoCart function is being called but, the update is not happening. No errors are being shown either

MY shopping cart component is

export default class Cart extends Component {
    render() {
        const {cartItems} = this.props
        return (
            <div>
                {cartItems.length === 0 ? ( 
                    <div className='cart cart-header'>Cart is empty</div>
                    ) : (
                    <div className='cart cart-header'>You have {cartItems.length} items in yout cart{" "}</div>
                    )
                }
</div>

My code to add the item to cart in App js is :

addToCart = (product) => {
    const cartItems = this.state.cartItems.slice();
    console.log(cartItems); 
    let alreadyInCart = false;
    cartItems.forEach((item) => {
      if(item._id === product._id) { 
      item.count++;
      alreadyInCart=true;
    }
    if(!alreadyInCart) {
      cartItems.push({...product, count:1});
    }
  })
    this.setState({cartItems});
    console.log(this.state.cartItems)
  };

Upvotes: 0

Views: 117

Answers (1)

Drew Reese
Drew Reese

Reputation: 203466

Issues

  • item.count++; is a state mutation
  • You can't console log state right after a state update and expect it to log the the state from the next render cycle.

Solution

  • Search the array first to detect if the cart already contains item.
  • Use a functional state update.
  • Shallow copy the array and individual elements you update
  • Log state in a lifecycle function, i.e. componentDidUpdate after the state has been updated. In a pinch you can use the second argument to setState, a callback function, but this isn't recommended.

Code

addToCart = product => {
  const foundIndex = this.state.cartItems.findIndex(
    item => item._id === product._id
  );

  if (foundIndex !== -1) {
    this.setState(cartItems =>
      cartItems.map((item, i) =>
        i === foundIndex
          ? { ...item, count: item.count + 1 } // copy item and update count property
          : item
      )
    );
  } else {
    this.setState(cartItems => [...cartItems, { ...product, count: 1 }]);
  }
};

componentDidUpdate() {
  console.log(this.state.cartItems);
}

Upvotes: 1

Related Questions