Redux preloadedState 导致覆盖默认减速器状态(以及随后的未定义错误)?
Redux preloadedState causing override (and subsequent undefined error) of default reducer state?
我目前正在使用 react-redux 创建一个网站,并且在 createStore 中的 preloadedState 变量中出现拼写错误。我的相关商店代码如下(注意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}
}
在我的 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
}
我注意到这会在 existItem
行引发 Unhandled Rejection (TypeError): state.cartItems is undefined
错误。为什么添加 preloadedState 会导致这个问题?根据我的理解,reducer 的默认状态(在这种情况下由 state = {cartItems: []}
给出)应该仍然可以从 reducer 内部访问?不是这样吗?
这是设计使然。来自文档 Initializing State:
Without combineReducers()
or similar manual code, preloadedState
always wins over state = ...
in the reducer because the state passed to the reducer is preloadedState
and is not undefined
, so the ES6 argument syntax doesn't apply.
With combineReducers()
the behavior is more nuanced. Those reducers whose state is specified in preloadedState
will receive that state. Other reducers will receive undefined
and because of that will fall back to the state = ...
default argument they specify.
对于您的情况,preloadedState
是 {cart: { cartitems: cartItemsFromStorage }}
,{ cartitems: cartItemsFromStorage }
对象将在 cartReducer
中传递,因为它是默认状态 而不是ES6 默认参数语法.
这就是为什么您的购物车状态形状是 {cartitems: cartItemsFromStorage}
如果 preloadedState
是 undefined
,那么您的购物车默认状态是 {cartItems: []}
。
我目前正在使用 react-redux 创建一个网站,并且在 createStore 中的 preloadedState 变量中出现拼写错误。我的相关商店代码如下(注意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}
}
在我的 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
}
我注意到这会在 existItem
行引发 Unhandled Rejection (TypeError): state.cartItems is undefined
错误。为什么添加 preloadedState 会导致这个问题?根据我的理解,reducer 的默认状态(在这种情况下由 state = {cartItems: []}
给出)应该仍然可以从 reducer 内部访问?不是这样吗?
这是设计使然。来自文档 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.
With
combineReducers()
the behavior is more nuanced. Those reducers whose state is specified inpreloadedState
will receive that state. Other reducers will receiveundefined
and because of that will fall back to thestate = ...
default argument they specify.
对于您的情况,preloadedState
是 {cart: { cartitems: cartItemsFromStorage }}
,{ cartitems: cartItemsFromStorage }
对象将在 cartReducer
中传递,因为它是默认状态 而不是ES6 默认参数语法.
这就是为什么您的购物车状态形状是 {cartitems: cartItemsFromStorage}
如果 preloadedState
是 undefined
,那么您的购物车默认状态是 {cartItems: []}
。