开发者问题收集

React js 增加数组中现有对象的计数

2021-04-04
1172

我正在创建一个简单的 销售点 系统和我的 购物车减速器

我需要检查 对象 是否已在 购物车数组 中,然后增加数量。如果 对象 不存在,则将其推入 购物车数组

代码按预期运行。但有没有更好的解决方法?

购物车减速器

export const cartReducer = (state: IState, action: Actions) => {
const { uid } = action.payload

switch (action.type) {
    case 'ADD_TO_CART': {
        const cart_item = state.cart.filter(item => item.uid === uid)

        if (cart_item.length > 0) {
            return {
                ...state,
                cart: state.cart.map(item => item.uid === uid ? { ...item, quantity: item.quantity + 1 } : item)
            }
        }

        return {
            ...state,
            cart: [...state.cart, action.payload]
        }
    }
}
}
2个回答

在我看来这基本合理,但你可以通过以下方法略微改进:

  • 提前声明新的 cart ,而不是返回两次
  • 使用 some ,而不是 filter
case 'ADD_TO_CART': {
    const exists = state.cart.some(item => item.uid === uid);
    const cart = exists
        ? state.cart.map(item => item.uid === uid ? { ...item, quantity: item.quantity + 1 } : item)
        : [...state.cart, action.payload];
    return {
        ...state,
        cart
    };
}
CertainPerformance
2021-04-04

您无需对所有项目进行两次循环(一次用于过滤,一次用于映射),只需使用 findIndex 即可。

findIndex 相对于 filter 的优势在于:一旦满足条件,迭代就会停止,并且您将获得其索引,而不像 filter 那样,循环会迭代数组中的所有元素。

如果您的数组元素较少,则您的解决方案没问题,但在长数组的情况下, findIndex 会提供更好的性能。

switch (action.type) {
    case 'ADD_TO_CART': {
        const cartItemIndex = state.cart.findIndex(item => item.uid === uid)
        const updatedCart = [...state.cart]

        if (cartItemIndex > -1) {
            updatedCart[cartItemIndex] = { ...updatedCart[cartItemIndex], quantity: item.quantity + 1 }
        }
        else {
            updatedCart.push(action.payload)
        }

        return {
            ...state,
            cart: updatedCart
        }
    }
}
Ashish
2021-04-04