我有一个Redux reducer,我试图在我的reduce中嵌套一个对象数组,但它正在破坏。我似乎无法访问数组中的任何内容。但是,如果我从reducer返回一个数组而不是一个对象,它可以正常工作。
const friendReducer = (state = {}, action) => {
console.log(action);
switch (action.type) {
case 'GET_FRIENDS':
return {
list: [
...state,
...action.payload,
],
};
default:
return state;
}
};
export default friendsReducer;
当我尝试访问连接组件中的list
时,我无法访问Array#splice
方法或Array#length
属性。以下是代码的其他相关部分:
const mapStateToProps = (state) => {
return {
friends: state.friends,
}
};
const rootReducer = {
friends: friendsReducer,
};
const store = createStore(
combineReducers({
...rootReducer,
router: routerReducer,
}),
{}, // initial state
compose(
applyMiddleware(thunk),
applyMiddleware(routerMiddleware(history)),
// eslint-disable-next-line no-underscore-dangle
(typeof window.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined') ? window.__REDUX_DEVTOOLS_EXTENSION__() : f => f,
),
);
export default store;
你有一些问题。首先,friendsReducer
的状态片返回一个对象,而不是一个数组。所以你的州看起来像这样:
{
friends: {
list: […]
}
}
所以当你mapStateToProps
时,如果你想要数组,它应该是这样的:
return {
friends: state.friends.list //not state.friends, that's an object
}
接下来,还要注意您的初始状态中不包含list
:
const friendReducer = (state = {}, action) => { … }
因此,当您第一次尝试访问length
的list
时,将没有list
属性,因此您必须在初始状态内将其设置为空数组。始终使用所有属性设置初始状态:
const friendReducer = (state = { list: [] }, action) => { … }
最后,你在reducer中传播了错误的state属性:
case 'GET_FRIENDS':
return {
...state, //here use ...state to spread previous state
list: [
...state.list, //not state, use state.list to spread previous list
...action.payload,
],
};
你想传播旧的list
,所以你应该传播state.list
,而不是state
本身。此外,你可以在...state
之外添加list
以扩展之前的状态以获得良好的衡量标准,假设你将有不止一个动作,尽管它仍然是良好的做法。