【问题标题】:Can't get state to update array inside of an object correctly in REACT/REDUX无法在 REACT/REDUX 中正确获取状态以更新对象内部的数组
【发布时间】:2017-07-05 19:00:02
【问题描述】:

我将逐步分解我想要发生的事情,希望人们能够理解我想要什么。

使用 React/Redux、Lodash

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

  2. 然后我 dispatch type GET_ALL_POSTS 并触发 reducer reducer_posts 更改/更新状态。

减速器:

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. 正如我所提到的,每个帖子都有一个 cmets 值,它是一个数组。我想将 cmets 数组更改为一个大对象,该对象将每个评论保存为一个对象,其键等于它们的“_id”,就像我在帖子中所做的那样。
  3. 现在我需要一次性完成所有这些并返回新创建的状态,其中一个包含所有帖子作为对象的大对象,并且在每个帖子上应该有一个 cmets 对象,其中包含所有作为对象的 cmets。我将尝试编写一些示例代码来展示我正在尝试做的事情。

例子:

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

我希望这个示例能够阐明我正在尝试做的事情。如果仍然对我在做什么感到困惑,那么请询问,也请不要说使用数组之类的东西。我知道我可以使用数组,但这对这篇文章没有帮助,就好像其他人想这样做一样,这不是有用的信息。

【问题讨论】:

    标签: javascript reactjs redux lodash


    【解决方案1】:

    编写一个函数,为您在帖子数组中的每个帖子处理 cmets 数组中的所有 cmets:

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

    现在使用该函数将每个 cmets 数组变成一个包含所有 cmets 的大对象,同时它仍然在数组中。然后将数组本身变成一个大对象:

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

    【讨论】:

      【解决方案2】:

      我相信现在的 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

      【讨论】:

      • 这里为什么使用reduce?
      • reduce 是一种在转换最终数据时循环遍历数组的方法。在这种情况下,它会返回一个输出(对象)。请注意,我传递给回调的posts 参数是一个累加器,它将成为您最终的transformPost
      • 你将如何使用纯 js 重现这个?而不是使用 lodash?
      • 对不起。我已经离开了。这是使用纯 js jsbin.com/munureh/4/edit?js,console 对 js bin 的更新,您可以看到它很冗长,但 js 可以做到。我相信随着时间的推移,这些数据操作库会逐渐淡出。他们仍然有一些用例
      猜你喜欢
      • 2020-11-11
      • 2020-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 2018-03-20
      相关资源
      最近更新 更多