为什么我的 if/else 块在 Redux 工具包缩减器中不起作用?



所以基本上我正在制作一个购物车,我想添加一个功能,如果一个项目已经在购物车中,那么增加它的数量1。如果您添加相同的项目,他们有不同的大小,然后分别显示他们。我设法处理增加减速器逻辑中的数量,但当我添加另一个块条件时,它不起作用。下面是代码:

import { createSlice } from "@reduxjs/toolkit";
const initialState = {
bagData: [],
};
export const bagDataSlice = createSlice({
name: "bagDataProducts",
initialState,
reducers: {
sendDataToCardComponent: (state, action) => {
let { id, size } = action.payload;
const findItemById = state.bagData.find(
(item) => item.id === id && item.size === size
);
if (findItemById) {
state.bagData.filter((item, i) => (state.bagData[i].quantity += 1));
} else {
state.bagData.push({ ...action.payload, quantity: 1 });
}
},
increaseItemQuantity: (state, { payload }) => {
state.bagData.filter((item, i) =>
item.id === payload ? (state.bagData[i].quantity += 1) : item
);
},
decreaseItemQuantity: (state, { payload }) => {
state.bagData.filter((item, i) =>
item.id === payload && item.quantity > 1
? (state.bagData[i].quantity -= 1)
: item
);
},
removeItem: (state, { payload }) => {
state.bagData = state.bagData.filter((item) => item.id !== payload);
},
},
});
当我添加 条件时
const findItemById = state.bagData.find(
(item) => item.id === id && item.size === size
);

它只增加项目而不检查它的大小,只检查它的id,即使有两个条件的函数。你能给我解释一下吗?

state.bagData.filter((item, i) => (state.bagData[i].quantity += 1));

对于第一种情况,这是更新每个如果您通过idsize找到匹配的项目,则该项目的数量。既然你已经找到了项目并将其存储在findItemById中,你应该能够使用以下命令。

注意,Immer只支持通过索引改变数组元素,所以使用findIndex()代替find()

const itemIndex = state.bagData.findIndex(
(item) => item.id === id && item.size === size
);
if (itemIndex !== -1) {
state.bagData[itemIndex].quantity++;
} else {
state.bagData.push({ ...action.payload, quantity: 1 });
}

这里有一个快速的演示,显示这是有效的

const initialState = {
bagData: [{
id: 1,
quantity: 1,
size: "S"
}]
};
const sendDataToCardComponent = (action) =>
immer.produce(initialState, (state) => {
let { id, size } = action.payload;
const itemIndex = state.bagData.findIndex(
(item) => item.id === id && item.size === size
);
if (itemIndex !== -1) {
state.bagData[itemIndex].quantity++;
} else {
state.bagData.push({ ...action.payload, quantity: 1 });
}
});
console.log(
"increment existing",
sendDataToCardComponent({ payload: { id: 1, size: "S" } })
);
console.log(
"add new",
sendDataToCardComponent({ payload: { id: 1, size: "M" } })
);
.as-console-wrapper { max-height: 100% !important; }
<script src="https://cdn.jsdelivr.net/npm/immer"></script>


正如在评论中提到的,你误用了array .prototype.filter(),它应该只用于返回一个新的数组,其中包含基于谓词过滤的条目。你的代码可以稍微清理一下

increaseItemQuantity: (state, { payload }) => {
const found = state.bagData.findIndex(({ id }) => id === payload);
if (found !== -1) {
state.bagData[found].quantity++;
}
},
decreaseItemQuantity: (state, { payload }) => {
const found = state.bagData.findIndex(({ id }) => id === payload);
if (found !== -1) {
state.bagData[found].quantity--;
}
},

您的最后一个减速机正确使用filter(),但Immer也支持splice()

removeItem: (state, { payload }) => {
const found = state.bagData.findIndex(({ id }) => id === payload);
if (found !== -1) {
state.bagData.splice(found, 1);
}
},

最新更新