无法获取状态在REACT / REDUX中正确更新对象内部的数组

时间:2017-07-05 19:00:02

标签: javascript reactjs redux lodash

我将逐步打破我想要发生的事情,希望人们能够理解我想要的东西。

使用React / Redux,Lodash

  1. 我有很多帖子是从后端api作为数组发送的。每个帖子都有一个_id。当我调用动作getAllPost()时,它会将所有帖子返回给我。这工作得很好。

  2. 然后我调度类型GET_ALL_POSTS并触发缩减器reducer_posts来更改/更新状态。

  3. 减速器:

    export default function(state = {}, action) {
      switch(action.type) {
        case GET_ALL_POSTS:
        const postsState =  _.mapKeys(action.payload.data, '_id');
        //const newPostsState = _.map(postsState, post => {
          //const newComments = _.mapKeys(post.comments, '_id');
        //});
          return postsState;
        break;
        default:
          return state;
        break;
      }
    }
    
    1. 正如您所看到的,我将数组更改为一个巨大的对象,其中包含许多帖子作为对象,其键与“_id”相等。这工作得很好,返回这部分状态也可以正常工作。
    2. 正如我所提到的,这些帖子中的每一个都有一个数组的注释值。我想将comments数组更改为一个大对象,该对象将每个注释保存为一个对象,其密钥等于它们的'_id',就像我在帖子中所做的那样。
    3. 现在我需要立即执行此操作并返回新创建的状态,其中包含一个包含所有帖子作为对象的大对象,并且在每个帖子上应该有一个包含所有注释作为对象的注释对象。我将尝试编写一些示例代码来显示我想要做的事情。
    4. 示例:

      BigPostsObject { 
      1: SinglePostObject{}, 
      2: SinglePostObject{}, 
      3: SinglePostObject {
        _id: '3',
        author: 'Mike',
        comments: BigCommentObject{1: SingleCommentObject{}, 2: SingleCommentObject{}}
       }
      }
      

      我希望这样的例子可以清除我想要做的事情。如果它仍然令我感到困惑,那么请问,也请不要说像使用数组。我知道我可以使用一个数组,但这对这篇文章没有帮助,好像其他人想要这样做,这不是有用的信息。

2 个答案:

答案 0 :(得分:0)

我相信现在JS内置函数可以在不需要外部库的情况下完成此操作。无论如何这应该是要走的路。我真的很鼓励你回到js内置函数。

var data = [
 {
  _id: '3',
  title: 'Going on vaccation',
  comments:[ 
    {_id: 1, comment: 'hello'},
    {_id: 2, comment: 'world'}           
  ] 
 }, 

 {
  _id: '2',
  title: 'Going to dinner',
  comments:[ 
    {_id: 1, comment: 'hello'},
    {_id: 2, comment: 'world'}           
  ] 
 } 

]

//you can use JS builtin reduce for this
var transformedPost= _.reduce(data, function(posts, post) {
  var newPost = Object.assign({}, post)
  newPost._id=post._id
  //you can use js builtin map for this 
  newPost.comments = _.mapKeys(post.comments, '_id')

  // if you are using es6, replace the last three line with this 
  //return Object.assign({}, posts, {[newPost._id]: newPost})

  var item = {}
  item[newPost._id]=newPost
  return Object.assign({}, posts, item)
},{});

console.log(transformedPost)

https://jsbin.com/suzifudiya/edit?js,console

答案 1 :(得分:0)

编写一个函数,处理posts数组中每个帖子的所有注释:

function processComment(post) {
   post.bigCommentsObject = _.mapKeys(post.comments, '_id');
   // now the comments array is no longer needed
   return _.omit(post, ['comments']);

}

现在使用该函数将每个注释数组转换为一个大对象,其中所有注释仍然在数组中。然后将数组本身转换为一个大对象:

const commentsProcessed =  _.map(action.payload.data, procesComment);
const postsState =  _.mapKeys(commentsProcessed, '_id');