Ad

State Updating In Redux

- 1 answer

I'm a newbie in redux and es6 syntax. Here the problem:

There is an app with multiple posts.

const initialState = {
  items: {
    3: {title: '1984'}, 
    6: {title: 'Mouse'}, 
    19:{title: 'War and peace'}
  }
}

App receive an array of liked posts ids:

dispatch(receiveLikedPosts(3, {id:3, ids: [3,6]}));

function receiveLikedPosts(ids) {
  return {
    type: LIKED_POSTS_RECEIVED,
    ids
  };
}

There is a posts reducer:

function posts(state = initialState, action) {
  switch (action.type) {
  case LIKED_POSTS_RECEIVED:
    // here I need to update my posts state: post.liked => true (only 3 and 6 post) 
  default:
    return state;
  }
}

1) I have to update my reducers LIKED_POSTS_RECEIVED code. Dunno how to make it in right way.

2) Is it correct to dispatch events multiple times? ( one dispatch for each liked post)

Here the code:

// action
let ids = [3,6]
for (let id of ids) {
  dispatch({type: LIKE, id});
}

// reducers
function post(state, action) {
  switch (action.type) {
  case LIKE:
    return Object.assign({}, state, {
      liked: true
    });
  default:
    return state;
  }
}

function posts(state = initialState, action) {
  switch (action.type) {
  case LIKE:
    return Object.assign({}, state, {
      [action.id]: post(state[action.id], action)
    });
  default:
    return state;
  }
}
Ad

Answer

This is confusing to me:

dispatch(receiveLikedPosts(3, {id:3, ids: [3,6]}));

function receiveLikedPosts(ids) {
  return {
    type: LIKED_POSTS_RECEIVED,
    ids
  };
}

Your function receiveLikedPosts only accepts one argument, yet you're passing it two. And I'm not sure what { id: 3, ids: [3, 6] } is supposed to be doing. But, here's what I would do:

Initial state and reducer:

const initialState = {
  items: {
    3: { title: '1984', liked: false }, 
    6: { title: 'Mouse', liked: false }, 
    19: { title: 'War and peace', liked: false }
  }
};

function posts(state = initialState, action) {
  switch (action.type) {
    let newItems = {};

    case LIKED_POSTS_RECEIVED:
      // copy the current items into newItems
      newItems = {...state.items};

      // Loop through the liked IDs, set them to liked:true
      action.ids.forEach((likedId) => {
        newItems[likedId].liked = true;
      });

      // Return the new state
      return {
        ...state,
        items: newItems,
      }
    default:
      return state;
  }
}

Action creator:

function receiveLikedPosts(ids) {
  return {
    type: LIKED_POSTS_RECEIVED,
    ids,
  };
}

And finally, the dispatch:

dispatch(receiveLikedPosts([3, 6]));
Ad
source: stackoverflow.com
Ad