#javascript #reactjs #redux
#javascript #reactjs #redux
Вопрос:
У меня уже некоторое время возникает эта проблема, и, похоже, я не могу ее исправить. Мое веб-приложение работало нормально, пока я не начал получать эту ошибку несколько недель назад, когда я хотел добавить некоторые функции. Я не знаю, в чем может быть проблема, поскольку я все еще новичок в ReactJS, и даже при попытках возврата к последней рабочей фиксации проблема все еще сохраняется. Мне нужна помощь, чтобы исправить это. Я продолжаю получать ошибку:
Ошибка типа: не удается прочитать свойство ‘reduce’ неопределенного
каждый раз, когда я запускаю свое приложение. В нем говорится, что ошибка находится в моем файле селектора, который находится ниже, и конкретно в блоке selectCartItemsCount .
import { createSelector } from 'reselect';
const selectCart = (state) => state.cart;
export const selectCartItems = createSelector(
[selectCart],
(cart) => cart.cartItem
);
export const selectCartHidden = createSelector(
[selectCart],
(cart) => cart.hidden
);
export const selectCartItemsCount = createSelector([selectCartItems], (cartItems) =>
cartItems.reduce(
(accumulatedQuantity, cartItem) =>
accumulatedQuantity cartItem.quantity,
0
)
);
Я экспортирую этот селектор в свой компонент, который выглядит следующим образом:
import React from 'react';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
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.scss';
const CartIcon = ({ toggleCartHidden, itemCount }) => (
<div className="cart-icon" onClick={toggleCartHidden}>
<ShoppingIcon className="shopping-icon" />
<span className="item-count">{itemCount}</span>
</div>
);
const mapSateToProps = createStructuredSelector({
itemCount: selectCartItemsCount,
});
const mapDispatchToProps = (dispatch) => ({
toggleCartHidden: () => dispatch(toggleCartHidden()),
});
export default connect(mapSateToProps, mapDispatchToProps)(CartIcon);
Мой редуктор корзины выглядит следующим образом:
import CartActionTypes from './cart.types';
import { addItemToCart, removeItemFromCart } 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_ITEMS:
return {
...state,
cartItems: addItemToCart(state.cartItems, action.payload),
};
case CartActionTypes.REMOVE_ITEM:
return {
...state,
cartItems: removeItemFromCart(state.cartItems, action.payload),
};
case CartActionTypes.CLEAR_ITEM_FROM_CART:
return {
...state,
cartItems: state.cartItems.filter(
(cartItem) => cartItem.id !== action.payload.id
),
};
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 }];
};
Комментарии:
1. Я не чувствую, что здесь достаточно информации, чтобы ответить на ваш вопрос. Вы пробовали устанавливать точки останова или консоль. ведение журнала, чтобы убедиться
cartItems
, что оно определено и является массивом, прежде чем вызывать.reduce
его?2. Возможно, это связано с тем, что это асинхронная задача, и, возможно
cartItems
, она не была извлечена из серверной части, поскольку она извлекается только после монтирования (и даже определяется после завершения асинхронного процесса, я полагаю, но до того, как это произойдет, ваш сайт выйдет из строя.) Я думаю, что решением должно быть либо предоставить ему начальное значение пустого массива, либо проверять каждое использование переменной., .3. Привет @TKoL, так что да, предыдущий массив — это селектор ввода, из которого я получаю свои заголовки. У меня также есть промежуточное программное обеспечение, называемое redux-logger, которое записывает предыдущие состояния до выполнения действий и состояния после выполнения действий. У меня не было ни одного товара в корзине до его сбоя, поэтому я не вижу никакого журнала корзины.
4. Что вы получаете, когда вы
console.log(cartItems)
?5. Привет @AnkushVerma, итак, в моем редукторе начальное состояние cartItems является пустым массивом и заполняется только после ввода элементов. Какие-либо другие решения?