使用reducer更新状态内的特定值

时间:2019-12-13 22:02:51

标签: javascript arrays reactjs object redux

我正在尝试在状态内的对象数组内更新特定值(在这种情况下为列表内的注释)。在这种情况下, msgs 键中的注释。

 const list = [{
    id: 1,
    text: "list text",
    msgs: [{
      id: 1,
      comment: "comment",
      commentID: "ab37afa-c17-e4f-f103-4715b72f14ec"
    }]
  },
  {
    id: 2,
    text: "list text 2",
    msgs: [{
      id: 2,
      comment: "comment2", <--- trying to update this value
      commentID: "ab37afa-c17-e4f-f103-4715b72f14ec-2"
    },
    {
      id: 2,
      comment: "comment3",
      commentID: "ab37afa-c11323127-e4f-f103-4715b72f14ec-2"
    }]
  }
];

我目前正在尝试使用reducer:

case "EDIT_COMMENT":
      temp = state.filter((list => list.id === parseInt(action.comment.id)))  //getting the list that I want
      const msgs = [].concat(...temp).map(x=> ({
        id: x.id,
        comment : x.comment,
        commentID : x.commentID
        })) // trying to get the messages inside the state


     // I honestly don't know what to put here
      return msgs.map( msg => {
        if(msg.commentID === action.payload.commentID){
          return {...}
        }
      }        
        )

如果有人可以帮助我解决该问题,我将无法获得答案/解决方案来更新我想要的数据,我将不胜感激。 预先感谢,祝您周末愉快:)

3 个答案:

答案 0 :(得分:2)

如果我理解正确,那么您想更新msg的任何给定项目上的任何嵌套state注释(我认为与您问题中显示的列表形式相匹配)-在这种情况下,一个简单的解决方案可能如下:

case "EDIT_COMMENT": {

  return state.map(messageItem => {

    return {
      // Clone input messageItem
      ...messageItem,

      // Overwrite msgs field with new msgs array
      msgs : messageItem.msgs.map(commentItem => {

        if(commentItem.commentID === action.payload.commentID) {
          return {
            // Clone input commentItem
            ...commentItem,

            // Overwrite fields that this action should update,
            // on commentItem matching by comment id ie, "comment"
            // from action payload
            comment : action.payload.comment
          }      
        }
        else {
          // If message does not match actions comment id, return
          // a clone of commentItem to mapped list
          return {...commentItem}
        }
      })
    }    
  });
}

这里的假设是这样

  • state是一个与list形式匹配的数组,如您的问题中所示
  • 动作有效负载中的commentId对于msg子数组中的注释是唯一的。
  • 操作有效负载中的comment字段包含新的注释字符串,以更新现有的匹配注释

希望有帮助!

答案 1 :(得分:1)

您要映射所有内容,除非匹配action.payload.commentID,否则请原样返回。如果匹配,则按原样返回THAT,除了更新注释。

const list = [{
    id: 1,
    text: "list text",
    msgs: [{
      id: 1,
      comment: "comment",
      commentID: "ab37afa-c17-e4f-f103-4715b72f14ec"
    }]
  },
  {
    id: 2,
    text: "list text 2",
    msgs: [{
      id: 2,
      comment: "comment2", // <--- trying to update this value
      commentID: "ab37afa-c17-e4f-f103-4715b72f14ec-2"
    },
    {
      id: 2,
      comment: "comment3",
      commentID: "ab37afa-c11323127-e4f-f103-4715b72f14ec-2"
    }]
  }
];

const action = {
  payload: {
    commentID: 'ab37afa-c17-e4f-f103-4715b72f14ec-2',
    comment: 'Updated Comment',
  }
}

console.log(list.map(listItem => {
  return {
    ...listItem,
    msgs: listItem.msgs.map(msg => {
      if (msg.commentID === action.payload.commentID) {
        return {
          ...msg,
          comment: action.payload.comment
        }
      }
      return msg;
    })
  }
}))

答案 2 :(得分:1)

这个怎么样? (我只是组成了动作的结构)

case "EDIT_COMMENT":
    return state.map((list) => {
        if (list.id === parseInt(action.listId) {
            list.msgs = list.msgs.map((msg) => {
                if (msg.id === action.commentId) {
                    msg.comment = action.comment;
                }
                return msg;
            }
        }
        return list;
    });
    break;