Search code examples
javascriptreduxreact-redux

Why is data.posts undefined when accessing using subscriber method in redux?


How can I access complete state in redux?

const { createStore } = require("redux");

const initialState = {
  posts: [
    { id: 1, title: "Post one" },
    { id: 2, title: "Post two" },
  ],
};

My Posts Reducer

const PostsReducer = (state = initialState, action) => {
  switch (action.type) {
    case "add_post":
      return {
        ...state,
        posts: [...state.posts, action.payload],
      };

    case "delete_post":
      return {
        ...state,
        posts: state.posts.filter((post) => post.id !== action.payload),
      };

    case "get_all_posts":
      return state.posts;

    default:
      return state;
  }
};

const store = createStore(PostsReducer);

My Action Creators:

const GetAllPosts = () => {
  return {
    type: "get_all_posts",
  };
};

const AddPost = (payload) => {
  return { type: "add_post", payload };
};

const removePost = (payload) => {
  return { type: "delete_post", payload };
};

Accessing Store data:

store.subscribe(() => {
  const data = store.getState();
  console.log(data.posts);
});

store.dispatch(GetAllPosts());

While I am console logging data.posts it returns undefined.

I am accessing using subscriber method:

store.subscribe(() => {
  const data = store.getState();
  console.log(data.posts);
});

store.dispatch(GetAllPosts());

Note:

I am Using Redux(4.2.1)

By using GetAllPosts(), I am able to access data, but I cannot get data.posts in console.


Solution

  • The get_all_posts case is returning the state.posts array directly instead of setting a state object with a posts property.

    case "get_all_posts":
      return state.posts; // <-- just the posts array
    

    Update get_all_posts case to return the correct state invariant, likely the initial state value with all the posts included.

    Example:

    const initialState = {
      posts: [
        { id: 1, title: "Post one" },
        { id: 2, title: "Post two" },
      ],
    };
    
    const PostsReducer = (state = initialState, action) => {
      switch (action.type) {
        case "add_post":
          return {
            ...state,
            posts: [...state.posts, action.payload],
          };
    
        case "delete_post":
          return {
            ...state,
            posts: state.posts.filter((post) => post.id !== action.payload),
          };
    
        case "get_all_posts":
          return { ...initialState };
    
        default:
          return state;
      }
    };