Actualmente estoy creando un sitio web con react-redux y recibí un error tipográfico en la variable preloadedState dentro de createStore. Mi código de tienda relevante es el siguiente (Observe la ortografía de cartitems en initialState en lugar de cartItems ):
const reducer = combineReducers({ productList: productListReducer, productDetails: productDetailsReducer, cart: cartReducer, }) const cartItemsFromStorage = localStorage.getItem('cartItems') ? JSON.parse(localStorage.getItem('cartItems')) : [] //BELOW GETS PASSED INTO createStore const initialState = { cart: {cartitems: cartItemsFromStorage} } Dentro de my cartReducer , el código afectado es el siguiente:
export const cartReducer = (state = {cartItems: []}, action) => { switch(action.type){ case CART_ADD_ITEM: const item = action.payload const existItem = state.cartItems.find(x => x.product === item.product) ***other code below...*** default: return state } Noté que esto arroja un Unhandled Rejection (TypeError): state.cartItems is undefined en la línea existItem . ¿Por qué la adición de preloadedState causa este problema? Según tengo entendido, el estado predeterminado del reductor (en este caso dado por state = {cartItems: []} ) ¿debería seguir siendo accesible desde dentro del reductor? ¿No es este el caso?
Esto es por diseño. Del documento Estado de inicialización :
Sin
combineReducers()o un código manual similar,preloadedStatesiempre gana astate = ...en el reductor porque el estado pasado al reductor espreloadedStatey no estáundefined, por lo que la sintaxis del argumento ES6 no se aplica.
Con
combineReducers()el comportamiento es más matizado. Aquellos reductores cuyo estado se especifique enpreloadedStaterecibirán ese estado. Otros reductores recibiránundefinedy, por eso, volverán al argumentostate = ...predeterminado que especifiquen.
Para su caso, el preloadedState es {cart: { cartitems: cartItemsFromStorage }} , el { cartitems: cartItemsFromStorage } se pasará en cartReducer como su estado predeterminado en lugar de la sintaxis de argumento predeterminada de ES6 .
Es por eso que la forma del estado de su carrito es {cartitems: cartItemsFromStorage}
Si preloadedState no está undefined , entonces el estado predeterminado de su carrito es {cartItems: []} .