1

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: []
    }
}

enter image description here

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.

1
  • Is the payload of post action expected to be an array or single object? Because it's named addPosts but you don't pass an array to it Commented Oct 13, 2017 at 7:20

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

7 Comments

i put your code in and i get the same issue as the one i state before.
@StrahinjaAjvaz Would you please write down the action.js file that addPosts action creator is?
And reducer.js that combineReducers is?
@StrahinjaAjvaz To understand easily, change name of posts reducer or implement combineReducers like combineReducers({postStore: posts, cat}).
|
1

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.

5 Comments

still comes back with a nested posts unfortunately :(
could you put the whole app inside git ? I could take a look. Because something doesn't seem right.
Ok I figured it out.
what was the issue?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.