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本身