Estoy tratando de actualizar la cantidad presionando el botón "arriba".
Este es mi código.
const increaseHandler = (x) => { let newCart = [...props.cartItems]; let exist = newCart.find((item) => item.id === x.id); if (exist) { exist.quantity++; } else { exist = { ...props.cartItems, quantity: 1, }; } newCart.push(exist); props.setCartItems(newCart); };Aquí está el botón:
<button className="up" onClick={() => increaseHandler(items)}> up </button>Cada vez que hago clic en el botón "arriba", agrega un duplicado del artículo en el carritoItems
Aumenté la cantidad pero agrega el objeto a la matriz.
A pesar de que ha copiado superficialmente la matriz de elementos del carrito, todavía está mutando los elementos individuales con el incremento posterior.
const increaseHandler = (x) => { let newCart = [...props.cartItems]; let exist = newCart.find((item) => item.id === x.id); if (exist) { exist.quantity++; // <-- mutation!! } else { exist = { ...props.cartItems, quantity: 1, }; } newCart.push(exist); // <-- adds duplicate items props.setCartItems(newCart); }; Todavía necesita crear una nueva referencia de artículo, copiar superficialmente las propiedades y actualizar la propiedad de quantity . Solo debe insertar nuevos elementos en la matriz del carrito.
const increaseHandler = (x) => { const newCart = [...props.cartItems]; let exist = newCart.find((item) => item.id === x.id); if (exist) { exist = { ...exist, quantity: exist.quantity + 1; }; } else { exist = { ...props.cartItems, quantity: 1, }; newCart.push(exist); } props.setCartItems(newCart); };Es más común asignar el estado anterior al estado siguiente, y sugiero usar una actualización de estado funcional para garantizar la actualización correcta desde el estado anterior frente a cualquier estado cerrado en el ámbito de devolución de llamada ( posiblemente obsoleto ).
const increaseHandler = (x) => { props.setCartItems(items => { const inCart = items.some((item) => item.id === x.id); if (inCart) { return items.map((item) => item.id === x.id ? { ...item, quantity: item.quantity + 1, } : item); } return items.concat({ ...props.cartItems, quantity: 1, }); }); };Puedes actualizar usando el map :
const increaseHandler = (x) => { props.setCartItems((preState) => preState.map((item) => (item.id === x.id ? { ...item, quantity: item.quantity + 1 } : item)), ); };Está configurando toda la matriz cartItems en el único objeto exist que ha creado. Entonces, está agregando todo el carrito para que exist y luego configura exist.quantity en 1 , y empuja todo eso a newCart y lo configura en el estado.
Intente difundir exist en lugar de props.cartItems en su bloque else .
Según sus imágenes y nomenclatura, ¿es este el tutorial de FreeCodeCamp/Wiebenfalk sobre reaccionar y TS? Si es así, hice el mismo tutorial, y aquí está mi función de agregar al carrito:
const handleAddToCart = (clickedItem: CartItemType) => { setCartItems((prevState) => { // check if item is in cart by looking for id of clicked item in array of cartItems already in state const isItemInCart = prevState.find((item) => item.id === clickedItem.id); if (isItemInCart) { // search for item id matching clicked item; increment that amount return prevState.map((item) => item.id === clickedItem.id ? { ...item, amount: item.amount + 1 } : item ); } return [...prevState, { ...clickedItem, amount: 1 }]; }); };