0

In strict Mode, React runs twice to detect side effects. So I think I should not turn the strict Mode off, I should make sure that when running twice, the output still correct.

There is a product , when I add qty 3, run twice , the output will be 1 + 3 + 3 = 7.

It's a simple cart logic. When no item ,create an item and concat() it. It there is this item (qty>1 or findIndex() > 0), find it ,and edit its quantity. However, when run twice, add quantity will run twice too. How can I solve the problem?

export const CartContextProvider = props => {
  const defaultCart = { items: [], qty: 0, total: 0 }

  const cartReducer = (state, actions) => {
    if (actions.type === 'SUBMIT') {
      const [id, qty, price] = [
        actions.item.id,
        actions.item.qty,
        actions.item.price
      ]

       //ckeck if pd already exists
      const itemIndex = state.items.findIndex(el => {
        return el.id === id
      })
      // if no item ,add first item to cart
      if (itemIndex === -1 && +qty > 0) {
        const newItem = {
          id: id,
          qty: +qty,
          price: +price
        }

        const updatedItems = state.items.concat(newItem)
        const updatedQty = state.qty + +qty
        const updatedTotal = state.total + +qty * +price

        console.log(newItem.qty)

        return { items: updatedItems, qty: updatedQty, total: updatedTotal }
      } else {
        console.log('run')
        let findItem = state.items[itemIndex]

        const updatedItem = {
          id: id,
          qty: findItem.qty + +qty,   // here will run twice. 
          price: +price
        }
        const stateItems = state.items
        stateItems[itemIndex] = updatedItem
        console.log(updatedItem.qty)
        const updatedQty = state.qty + +qty
        const updatedTotal = state.total + +qty * +price

        return { items: stateItems, qty: updatedQty, total: updatedTotal }
      }
    }
    return defaultCart
  }

  const [cart, dispatchCart] = useReducer(cartReducer, defaultCart)

  function cartSubmitHandler (id, qty, price) {
    dispatchCart({ type: 'SUBMIT', item: { id: id, qty: qty, price: price } })
  }

  return (
    <CartContext.Provider
      value={{
        cart: cart,
        cartSubmitHandler: cartSubmitHandler
      }}
    >
      {props.children}
    </CartContext.Provider>
  )
}

export default CartContext

add twice to 7

Miki U
  • 21
  • 6

1 Answers1

0

The culprit is

 const stateItems = state.items

should be :

 const stateItems = [...state.items]

I slightly change the name of variables. Final code is presenting down below.

 use spread operator

Miki U
  • 21
  • 6