Хорошо, поэтому я попытаюсь объяснить и разобраться в этом.
По сути, я сделал состояние в хранилище React Hooks с 4 состояниями. Один для первоначального хранения продукта, второй для отображения текущего элемента, который, когда пользователи смотрят, даст им возможность добавить элемент в корзину, фактическую корзину и один для заказов. состояние сохраняется так:
import React, {createContext, useReducer} from "react";
import Reducer from './useStoreReducer'
const initialState = {
Items: [{
title : "Shoes",
description: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s",
price: "99.99",
imageUrl: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRVPjDPo_CNSGpoL5NfZL8XzLAzJsrf1-nB_7KP4MI9a55cxZzNsQ&s",
key: "random",
id: "random",
amount: 10,
totalAmount: 0
},
{
title : "Sweater",
description: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s",
price: "150",
imageUrl: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSntrbto9AejA8UIYyuExTkfIctDY8WEXr-MZxEoUbhypCAjhhN&s",
key: "shit",
id: "shit",
amount: 10,
totalAmount: 0
},
{
title : "Toy",
description: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s",
price: "200",
imageUrl: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSfZi9v8kkhaKgxJUe02vHi6jeguCm8h6H7Q0zdG6Nogm0deenxUA&s",
key: "here",
id: "here",
amount: 10,
totalAmount: 0
},],
Item: {
title : "empty",
description: "empty",
price: "empty",
imageUrl: "empty",
key: "empty",
id: "empty",
amount: 0,
totalAmount: 0
},
Cart: [],
Orders: [],
error: null
};
const Store = ({children}) => {
const [state, dispatch] = useReducer(Reducer, initialState);
return (
<Context.Provider value={[state, dispatch]}>
{children}
</Context.Provider>
)
};
export const Context = createContext(initialState);
export default Store;
У меня также есть страница для редукторов, например, так:
const useStoreReducer = (state, action) => {
switch(action.type) {
case 'ADD_NEW_ITEM' :
return {
...state,
Items: [...state.Items, action.payload]
}
case 'OPEN_CART' :
return {
...state,
Item: action.payload
}
case 'ADD_TO_CART' :
return {
...state,
Cart: [...state.Cart, action.payload]
}
case 'UPDATE_CART_AMOUNT' :
return {
...state,
Cart: action.payload
}
case 'ORDER' :
return {
...state,
Orders: [...state.Cart, action.payload]
}
default:
return state
}
}
export default useStoreReducer;
Так что теперь, в большинстве случаев, это работает как шарм, когда Я добавляю новый элемент, и он идет хорошо, когда я открываю корзину (щелчок по изображению элемента открывает модальное окно, в котором отображаются детали элемента), и добавление нового элемента также работает. В основном я составил список элементов, и когда вы нажимаете на элемент, Item вызывает модальный режим, который я сделал с помощью функции:
let [itemModal, toggleItemModal] = useState(false)
function openItem(id) {
if (!state.Items.id) {
dispatch ({
type: 'OPEN_CART',
payload: {
title : "empty",
description: "empty",
price: "empty",
imageUrl: "empty",
key: "empty",
id: null,
amount: 0,
totalAmount: 0
}
})
}
toggleItemModal(itemModal = !itemModal);
const filteredItem = state.Items.filter(item => item.id === id).pop() *//pop because it was returning an array and i needed an object to be displayed in the Item state. Now, I have an individual Item displayed when I click on an item*
dispatch({
type: 'OPEN_CART',
payload: filteredItem
});
console.log(state.Item)
}
Теперь я хочу убедиться, что когда пользователи нажмите на элемент и добавьте его в корзину, если элемент существует, обновите сумму, а не добавляйте новый элемент в корзину.
Итак, что я сделал, и исправьте меня, если я ошибаюсь, так как состояние неизменное, я попытался:
let cartCopy = state.Cart; //copy the state first
function addToCart(itemReference) {
const item = itemReference; //pass and as to not mutate the original state, this is the Item state
item.amount = parseInt(amount); //input handler to get the amount of items entered by the user
item.totalAmount = (amount*item.price);
if (state.Cart.some( cartItem => cartItem.id === item.id)) { //if item exists in the cart, yields true
let updatedCart = cartCopy.map( (cartItem) => { // tried to map through each item and if the ID exists, update the amount only
if (cartItem.id === item.id) {
cartItem.amount += parseInt(amount)
}
return cartItem;
}
)
console.log(updatedCart) //problem is, it only updates once and then it doesn't run again
} else {
alert("added to cart")
dispatch({
type: 'ADD_TO_CART',
payload: item
});
}
updatedAmount(amount = 1)
props.onHide()
}
Может кто-нибудь помочь мне увидеть, где я ошибся. Я новичок, поэтому меня не удивит, если я сделаю что-то не так, но я был очень осторожен и прочитал много документации, поэтому я прихожу сюда за помощью