我在使用redux时遇到麻烦。在我的减速器之一,其功能是添加到购物车。 我从数组中获取选定的项目作为对象(例如最近的产品)。不幸的是,在数组中我更改数量,数量也会在所选项目对象中自动更改。如果我更改对象,则持有对象的数组也会在同一执行中更改。我不确定为什么会这样。我的商店实现如下。
import { useMemo } from 'react';
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunkMiddleware from 'redux-thunk';
import {
products,
productsCollectionSix,
productsCollectionSeven,
productsCollectionEight,
productsCollectionNine,
productsCollectionTen,
productsCollectionEleven,
productsCovid19,
productsGrocery,
productsElectronics,
productsFurniture
} from '../json-data/products';
let store
import {
ADD_TO_CART,
REMOVE_ITEM,
SUB_QUANTITY,
ADD_QUANTITY,
ADD_SHIPPING,
ADD_QUANTITY_WITH_NUMBER,
RESET_CART,
ADD_TO_COMPARE,
REMOVE_ITEM_FROM_COMPARE,
UPDATE_RECENT_PRODUCTS,
TOGGLE_LOGIN_STATE
} from '../actions/action-types/action-names'
const initialState = {
products: products,
productsCollectionSix: productsCollectionSix,
productsCollectionSeven: productsCollectionSeven,
productsCollectionEight: productsCollectionEight,
productsCollectionNine: productsCollectionNine,
productsCollectionTen: productsCollectionTen,
productsCollectionEleven: productsCollectionEleven,
productsCovid19: productsCovid19,
productsGrocery: productsGrocery,
productsElectronics: productsElectronics,
productsFurniture: productsFurniture,
recentProducts: [],
addedItems: [],
addedItemsToCompare: [],
total: 0,
shipping: 0,
isLoggedIn: false
}
const reducers = (state = initialState, action) => {
//My add to cart function
if (action.type === ADD_TO_CART) {
//the selected item goes in itemToBeAdded
let itemToBeAdded = state.products.find((item) => {
if (item._id === action._id) {
item["array"] = "products";
return item;
}
})
|| state.productsCollectionSix.find((item) => {
if (item._id === action._id) {
item["array"] = "productsCollectionSix";
return item;
}
})
|| state.productsCollectionSeven.find((item) => {
if (item._id === action._id) {
item["array"] = "productsCollectionSeven";
return item;
}
})
|| state.productsCollectionEight.find((item) => {
if (item._id === action._id) {
item["array"] = "productsCollectionEight";
return item;
}
})
|| state.productsCollectionNine.find((item) => {
if (item._id === action._id) {
item["array"] = "productsCollectionNine";
return item;
}
})
|| state.productsCollectionTen.find((item) => {
if (item._id === action._id) {
item["array"] = "productsCollectionTen";
return item;
}
})
|| state.productsCollectionEleven.find((item) => {
if (item._id === action._id) {
item["array"] = "productsCollectionEleven";
return item;
}
})
|| state.productsCovid19.find((item) => {
if (item._id === action._id) {
item["array"] = "productsCovid19";
return item;
}
})
|| state.productsGrocery.find((item) => {
if (item._id === action._id) {
item["array"] = "productsGrocery";
return item;
}
})
|| state.productsElectronics.find((item) => {
if (item._id === action._id) {
item["array"] = "productsElectronics";
return item;
}
})
|| state.productsFurniture.find((item) => {
if (item._id === action._id) {
item["array"] = "productsFurniture";
return item;
}
})
|| state.recentProducts.find((item, index) => {
if (item._id === action._id) {
item["array"] = "recentProducts";
item["index"] = index;
return item;
}
})
let modifiedRecentProducts = [...state.recentProducts];
switch (itemToBeAdded["array"]) {
case "recentProducts":
if ((parseFloat(modifiedRecentProducts[itemToBeAdded["index"]].quantity.$numberDecimal) - 1) >= 0) {
//This is where i see things getting out of hands
//itemToBeAdded updates item in array and if modifiedRecentProducts item is updated first it updates itemToBeAdded quantity too.
modifiedRecentProducts[itemToBeAdded["index"]].quantity.$numberDecimal = parseFloat(modifiedRecentProducts[itemToBeAdded["index"]].quantity.$numberDecimal) - 1;
itemToBeAdded.quantity.$numberDecimal = 1;
return {
...state,
recentProducts: [...modifiedRecentProducts],
addedItems: [...state.addedItems, itemToBeAdded],
total: state.total + parseFloat(itemToBeAdded.salePrize.$numberDecimal)
}
}
break;
}
}
else {
return state
}
}
const initStore = (preloadedState = initialState) => {
return createStore(
reducers,
preloadedState,
composeWithDevTools(applyMiddleware(thunkMiddleware))
)
}
export const initializeStore = (preloadedState) => {
let _store = store ?? initStore(preloadedState)
// After navigating to a page with an initial Redux state, merge that state
// with the current state in the store, and create a new store
if (preloadedState && store) {
_store = initStore({
...store.getState(),
...preloadedState,
})
// Reset the current store
store = undefined
}
// For SSG and SSR always create a new store
if (typeof window === 'undefined') return _store
// Create the store once in the client
if (!store) store = _store
return _store
}
export const useStore = (initialState) => {
const store = useMemo(() => initializeStore(initialState), [initialState])
return store
}