[英]Redux preloadedState causing override (and subsequent undefined error) of default reducer state?
I currently am creating a website with react-redux and was getting an error with a typo in the preloadedState variable within createStore.我目前正在使用 react-redux 创建一个网站,并且在 createStore 中的 preloadedState 变量中出现拼写错误。 My relevant store code is as follows (Note the cartitems
spelling in initialState
instead of cartItems
):我的相关商店代码如下(注意在initialState
的cartitems
拼写而不是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}
}
Within my cartReducer
the code being affected is as follows:在我的cartReducer
中,受影响的代码如下:
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
}
I noticed that this throws an Unhandled Rejection (TypeError): state.cartItems is undefined
error on the existItem
line.我注意到这会引发Unhandled Rejection (TypeError): state.cartItems is undefined
error on the existItem
行。 Why does the addition of the preloadedState cause this issue?为什么添加 preloadedState 会导致这个问题? From my understanding the reducer's default state (in this case given by state = {cartItems: []}
) should still be accessible from within the reducer?根据我的理解,reducer 的默认状态(在这种情况下由state = {cartItems: []}
)应该仍然可以从 reducer 内部访问? Is this not the case?不是这样吗?
This is by design.这是设计使然。 From the doc Initializing State :从文档初始化状态:
Without
combineReducers()
or similar manual code,preloadedState
always wins overstate = ...
in the reducer because the state passed to the reducer ispreloadedState
and is notundefined
, so the ES6 argument syntax doesn't apply.如果没有combineReducers()
或类似的手动代码,preloadedState
总是在 reducer 中胜过state = ...
因为传递给 reducer 的 state 是preloadedState
而不是undefined
,所以 ES6 参数语法不适用。
With
combineReducers()
the behavior is more nuanced.使用combineReducers()
行为更加微妙。 Those reducers whose state is specified inpreloadedState
will receive that state.状态在preloadedState
指定的那些 reducer 将接收该状态。 Other reducers will receiveundefined
and because of that will fall back to thestate = ...
default argument they specify.其他减速器将收到undefined
,因此将退回到state = ...
默认参数。
For your case, the preloadedState
is {cart: { cartitems: cartItemsFromStorage }}
, the { cartitems: cartItemsFromStorage }
object will be passed in cartReducer
as it's default state rather than the ES6 default argument syntax .对于您的情况, preloadedState
是{cart: { cartitems: cartItemsFromStorage }}
, { cartitems: cartItemsFromStorage }
对象将在cartReducer
作为默认状态而不是 ES6 默认参数语法传递。
That's why your cart state shape is {cartitems: cartItemsFromStorage}
这就是为什么您的购物车状态形状是{cartitems: cartItemsFromStorage}
If the preloadedState
is undefined
, then your cart default state is {cartItems: []}
.如果preloadedState
是undefined
,那么您的购物车默认状态是{cartItems: []}
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.