Arrays 使用嵌套数组响应不可变对象的Redux更新状态,从数组中删除元素

Arrays 使用嵌套数组响应不可变对象的Redux更新状态,从数组中删除元素,arrays,reactjs,redux,immutability,react-redux,Arrays,Reactjs,Redux,Immutability,React Redux,我有以下对象,我想从中删除一条注释 msgComments = { comments: [ { comment:"2", id:"0b363677-a291-4e5c-8269-b7d760394939", postId:"e93863eb-aa62-452d-bf38-5514d72aff39" }, { comment:"1", id:"

我有以下对象,我想从中删除一条注释

    msgComments = {
        comments: [
            { comment:"2",
              id:"0b363677-a291-4e5c-8269-b7d760394939",
              postId:"e93863eb-aa62-452d-bf38-5514d72aff39" },
            { comment:"1",
              id:"e88f009e-713d-4748-b8e8-69d79698f072",
              postId:"e93863eb-aa62-452d-bf38-5514d72aff39" }
        ],
    email:"test@email.com",
    id:"e93863eb-aa62-452d-bf38-5514d72aff39",
    post:"test",
    title:"test" 
    }
action creator使用commentId点击api delete函数:

// DELETE COMMENT FROM POST

export function deleteComment(commentId) {
  return function(dispatch) {
    axios.post(`${API_URL}/datacommentdelete`, {
      commentId
    },{
      headers: { authorization: localStorage.getItem('token') }
    })
      .then(result => {
        dispatch({
          type: DELETE_COMMENT,
          payload: commentId
        });
      })
  }
}
我的api删除注释,我将注释id发送到我的Reducer,到目前为止工作正常,api工作正常,注释被删除。问题在于更新减速器中的状态。经过多次尝试和错误,目前我正在尝试这一点

case DELETE_COMMENT:
  console.log('State In', state.msgComments);
  const msgCommentsOne = state.msgComments;
  const msgCommentsTwo = state.msgComments;
  const deleteIndexComment = state.msgComments.data.comments
    .findIndex(elem => elem.id === action.payload );
  const newComments = [
    ...msgCommentsTwo.data.comments.slice(0, deleteIndexComment),
    ...msgCommentsTwo.data.comments.slice(deleteIndexComment + 1)
  ];
  msgCommentsOne.data.comments = newComments;
  console.log('State Out', msgCommentsOne);
  return {...state, msgComments: msgCommentsOne};
state in和state out都返回相同的对象,删除了相应的注释,这让我感到困惑

组件也没有更新(当我刷新时,注释消失了,因为一个新的api调用将返回更新后的帖子

其他一切似乎都很好,问题似乎出在减速器上


我已经阅读了其他与不变性相关的帖子,但我仍然无法找到解决方案。我也研究并找到了immutability.js库,但在我学会如何使用它之前,我想找到一个解决方案(可能是很难的,但我想了解它是如何工作的!).

第一个工作解决方案

case DELETE_COMMENT:
  const deleteIndexComment = state.msgComments.data.comments
    .findIndex(elem => elem.id === action.payload);

  return {
    ...state, msgComments: {
      data: {
        email: state.msgComments.data.email,
        post: state.msgComments.data.post,
        title: state.msgComments.data.title,
        id: state.msgComments.data.id,
        comments: [
          ...state.msgComments.data.comments.slice(0, deleteIndexComment),
          ...state.msgComments.data.comments.slice(deleteIndexComment + 1)
        ]
      }
    }
  };
编辑:

第二个工作方案

case DELETE_COMMENT:
  const deleteIndexComment = state.msgComments.data.comments
    .findIndex(elem => elem.id === action.payload);

  return {
    ...state, msgComments: {
      data: {
        email: state.msgComments.data.email,
        post: state.msgComments.data.post,
        title: state.msgComments.data.title,
        id: state.msgComments.data.id,
        comments: [
          ...state.msgComments.data.comments.slice(0, deleteIndexComment),
          ...state.msgComments.data.comments.slice(deleteIndexComment + 1)
        ]
      }
    }
  };
我找到了第二个更简洁的解决方案,欢迎评论:

case DELETE_COMMENT:
  const deleteIndexComment = state.msgComments.data.comments
    .findIndex(elem => elem.id === action.payload);

  return {
    ...state, msgComments: {
      data: {
        ...state.msgComments.data,
        comments: [
          ...state.msgComments.data.comments.slice(0, deleteIndexComment),
          ...state.msgComments.data.comments.slice(deleteIndexComment + 1)
        ]
      }
    }
  };

该代码似乎直接改变了状态对象。您创建了一个新数组,该数组已过滤掉已删除的项,但随后您将直接将新数组分配给
msgCommentsOne.data.comments
数据
字段与已处于该状态的字段相同,因此您直接修改了它不可变地更新数据,您需要创建一个新的
comments
数组,一个包含注释的新
data
对象,一个包含数据的新
msgComments
对象,以及一个包含msgComments的新
state
对象。一路向上:)

Redux常见问题解答确实提供了有关此主题的更多信息


我有许多文章的链接,这些文章讨论如何不可变地管理纯Javascript数据。此外,有多种实用程序库可以帮助抽象不可变地执行这些嵌套更新的过程,我已在中列出。

这就是为什么建议构建Redux存储的方法是保持状态更平坦和规范化:)仅供参考,我目前正在为Redux文档编写一组新的页面,描述如何编写reducer逻辑,处理规范化数据是其中的一部分。任务说明位于,并且有一个指向WIP页面的链接。你可能对阅读它们感兴趣。是的,解决方法可能是api本身