【问题标题】:Getting the following error - TypeError: cartItems.reduce is not a function收到以下错误 - TypeError: cartItems.reduce is not a function
【发布时间】:2021-03-28 20:59:42
【问题描述】:

我正在尝试使用 reduce 函数计算一个名为 cartItems 的数组中的项目数。但它每次都会抛出这个奇怪的错误。我的 redux 选择器代码 -

import { createSelector } from 'reselect';

const selectCart = state => state.cart;

export const selectCartItems = createSelector(
  [selectCart],
  cart => cart.cartItems
);

export const selectCartHidden = createSelector(
  [selectCart],
  cart => cart.hidden
);

export const selectCartItemsCount = createSelector(
  [selectCartItems],
  cartItems =>
    cartItems.reduce(
      (accumalatedQuantity, cartItem) =>
        accumalatedQuantity + cartItem.quantity,
      0
    )
);

我使用选择器的组件如下。我不是在 mapStateToProps 函数中解构它,而是直接传递选择器。

import React from 'react';
import { connect } from "react-redux";
import { toggleCartHidden } from "../../Redux/cart/cart.actions";
import { selectCartItemsCount } from '../../Redux/cart/cart.selectors';
import { ReactComponent as ShoppingIcon } from '../../assets/shopping-bag.svg';
import './cart-icon.styles.css';

const CartIcon = ({ itemCount, toggleCartHidden }) => (
    <div className='cart-icon' onClick={toggleCartHidden}>
        <ShoppingIcon className='shopping-icon' />
        <span className='item-count'>{itemCount}</span>
    </div>
);

const mapStateToProps = state => ({
    itemCount: selectCartItemsCount(state)
});

const mapDispatchToProps = dispatch => ({
    toggleCartHidden: () => dispatch(toggleCartHidden())
});

export default connect(
    mapStateToProps, 
    mapDispatchToProps)
(CartIcon);

这是购物车减速器 -

import CartActionTypes from './cart.types';
import { addItemToCart } from './cart.utils';

const INITIAL_STATE = {
  hidden: true,
  cartItems: []
};

const cartReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case CartActionTypes.TOGGLE_CART_HIDDEN:
      return {
        ...state,
        hidden: !state.hidden
      };
    case CartActionTypes.ADD_ITEM:
      return {
        ...state,
        cartItems: addItemToCart(state.cartItems, action.payload)
      };
    default:
      return state;
  }
};

export default cartReducer;

购物车实用功能 -

export const addItemToCart = (cartItems, cartItemToAdd) => {
    const existingCartItem = cartItems.find(
      cartItem => cartItem.id === cartItemToAdd.id
    );
  
    if (existingCartItem) {
      return cartItems.map(cartItem =>
        cartItem.id === cartItemToAdd.id
          ? { ...cartItem, quantity: cartItem.quantity + 1 }
          : cartItem
        )
    }
  
    return [...cartItems, { ...cartItemToAdd, quantity: 1 }];
  };

【问题讨论】:

  • 你的状态在 redux 中的形状是什么? state.cartstate.cart.cartItems 是什么? NM,您甚至还没有在mapStateToProps 中使用选择器...那么state.cart 是什么,那么您将重命名为cartItems?你是否打算从state.cart 解构cartItems 而不是:mapStateToProps = ({ cart: { cartItems } }) =&gt; ({...
  • @DrewReese cart 是减速器,而 cartItems 是项目数组。我确实解构了它。我已经编辑了答案以显示我如何在相应的组件中使用它。
  • 您是否尝试删除包裹在selectCartselectCartItems 中的createSelector 中的方括号?
  • @tuan.tran 不,我实际上已将它们保留在选择器中
  • @tuan.tran 这是输入选择器的有效重选语法。

标签: reactjs redux reselect redux-selector


【解决方案1】:

如果cardItems 为空或未定义,cardItems.reduce 将触发该错误。

使用cartItems || [] 将是解决方案。

export const selectCartItemsCount = createSelector(
  [selectCartItems],
  cartItems =>
    (cartItems || []).reduce(
      (accumalatedQuantity, cartItem) =>
        accumalatedQuantity + cartItem.quantity,
      0
    )
);

【讨论】:

  • 如果cartItems 是其他一些非数组真值,如{}true5 等呢?
猜你喜欢
  • 2015-10-11
  • 2017-07-22
  • 2020-11-17
  • 2022-10-07
  • 2021-08-20
  • 2022-01-01
  • 1970-01-01
  • 2017-09-01
  • 1970-01-01
相关资源
最近更新 更多