Reputation: 2643
I have the following code snippets:
action creator:
export function addCategories(cats){
return {
type: ADD_CATEGORY,
cats
}
}
reducer:
function posts(state = {posts: []}, action) {
switch (action.type) {
case ADD_POST: {
console.log(action.posts)
return {...state, posts: [...state['posts'], Object.assign({}, action.posts)]}
}
default:
return state
}
}
component:
import React, { Component } from 'react';
import { connect } from 'react-redux'
import { addCategories, addPosts } from './actions/index'
class App extends Component {
render() {
console.log(this.props)
return (
<div>
<button onClick={() => { this.props.cats({ name: "stra" }) }}>Add cat</button>
<button onClick={() => { this.props.posts({ age: 23 }) }}>Add post</button>
</div>
);
}
}
const mapStateToProps = (state) => {
console.log(state)
return {
state
}
}
const mapDispatchToState = (dispatch) => {
return {
cats: (cat) => dispatch(addCategories(cat)),
posts: (post) => dispatch(addPosts(post))
}
}
export default connect(mapStateToProps, mapDispatchToState)(App)
the propblem i have is that after the reducer is done, instead of getting the state looking like
{
// other values
posts: [] <- values go where
}
i get the state looking like this:
{
// other values
posts: {
posts: []
}
}
the image above is just what the console prints out when i run the code. Any advice on this would be greatly appreciated as i dont know where im going wrong.
Thanks in advance.
Upvotes: 1
Views: 166
Reputation: 764
The reducer which you implement is quite complicate.
Please try below.
const initialState = {
posts: [],
};
function posts(state = initialState, action) {
switch (action.type) {
case ADD_POST: {
let newState = {posts: state.posts};
newState.posts.push(...action.posts);
console.log(action.posts)
return Object.assign({}, state, newState);
}
default:
return state
}
}
UPDATE
It is caused by reducer's name posts
. You can solve this simply divide state
on mapPropsToState
like
function mapPropsToState(state) {
return {
posts: state.posts.posts,
cats: state.cats.cats,
}
}
It is a bad idea to make a reducer's name the same as a variable's name that the reducer contains.
Upvotes: 2
Reputation: 5075
So the problem is not the code, but your understanding of redux state and combine reducers.
what happens is that each reducer is responsible only for its own part of state, and only for it's own part of state.
You have 2 reducers, posts and cats. When you use combine reducers you are defining the state they are responsible for:
export default combineReducers({
cats,
posts
})
so now your redux store looks like this:
state: {
cats: {},
posts: {},
}
and each of these state properties have there own reducer, that manage that own state.
so in your case posts.posts is a valid redux state.
more information can be found here: http://redux.js.org/docs/recipes/reducers/UsingCombineReducers.html
if you want to see it your self in combine reducers change the code to be:
export default combineReducers({
cats,
postsStore: posts
})
and you will see it for your self.
Upvotes: 1