Reputation: 907
I have a Redux reducer and I am trying to nest an array of objects within my reduce, but it is breaking. I don't seem to have access to anything in the array. However, if I return an array instead of an object from the reducer it works fine.
const friendReducer = (state = {}, action) => {
console.log(action);
switch (action.type) {
case 'GET_FRIENDS':
return {
list: [
...state,
...action.payload,
],
};
default:
return state;
}
};
export default friendsReducer;
When I try to access the list
in my connected components, I can't access the Array#splice
method or Array#length
property. Here are other relevant parts of the code:
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;
Upvotes: 2
Views: 1413
Reputation: 57964
You've got a few problems. For one, friendsReducer
's slice of state returns an object, not an array. So your state looks like this:
{
friends: {
list: […]
}
}
So when you mapStateToProps
, it should look like this if you want the array:
return {
friends: state.friends.list //not state.friends, that's an object
}
Next, also notice that your initial state doesn't contain list
in it:
const friendReducer = (state = {}, action) => { … }
So when you first try to access the length
of list
, there will be no list
property, so you have to set it as an empty array inside your initial state. Always set up your initial state with all the properties:
const friendReducer = (state = { list: [] }, action) => { … }
Finally, you're spreading the wrong property of state in your reducer:
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,
],
};
You want to spread the old list
, so you're supposed to spread state.list
, not state
itself. Also, you can add ...state
outside of list
to spread the previous state for good measure, assuming you'll have more than one action, though its good practice nonetheless.
Upvotes: 3