React-Redux 使用嵌套数组更新不可变对象的状态,从数组中删除元素
React-Redux update state of immutable object with nested array, delete element from array
我有以下对象,我想从中删除一条评论。
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"
}
动作创建者点击 api 删除功能,评论 ID:
// 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};
声明和声明都 return 同一个对象,删除了我觉得令人费解的适当注释。
组件也没有更新(当我刷新时,注释消失了,因为对 return 进行了新的 api 调用,更新后的 post。
其他一切似乎都正常,问题似乎出在减速器上。
我已经阅读了其他 post 有关不变性的相关内容,但我仍然无法找到解决方案。我还研究并找到了 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: {
...state.msgComments.data,
comments: [
...state.msgComments.data.comments.slice(0, deleteIndexComment),
...state.msgComments.data.comments.slice(deleteIndexComment + 1)
]
}
}
};
该代码似乎直接改变了状态对象。您已经创建了一个新数组,其中过滤掉了已删除的项目,但您随后直接将新数组分配给 msgCommentsOne.data.comments
。 data
字段与状态中已有的字段相同,因此您直接修改了它。要正确地不可变地更新数据,您需要创建一个新的 comments
数组、一个包含评论的新 data
对象、一个包含数据的新 msgComments
对象和一个新的 state
包含 msgComments 的对象。一直向上链:)
Redux 常见问题解答在 http://redux.js.org/docs/FAQ.html#react-not-rerendering.
提供了关于此主题的更多信息
我在 https://github.com/markerikson/react-redux-links/blob/master/immutable-data.md . Also, there's a variety of utility libraries that can help abstract the process of doing these nested updates immutably, which I have listed at https://github.com/markerikson/redux-ecosystem-links/blob/master/immutable-data.md.
上有许多文章链接,这些文章讨论了不可变地管理普通 Javascript 数据
我有以下对象,我想从中删除一条评论。
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"
}
动作创建者点击 api 删除功能,评论 ID:
// 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};
声明和声明都 return 同一个对象,删除了我觉得令人费解的适当注释。
组件也没有更新(当我刷新时,注释消失了,因为对 return 进行了新的 api 调用,更新后的 post。
其他一切似乎都正常,问题似乎出在减速器上。
我已经阅读了其他 post 有关不变性的相关内容,但我仍然无法找到解决方案。我还研究并找到了 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: {
...state.msgComments.data,
comments: [
...state.msgComments.data.comments.slice(0, deleteIndexComment),
...state.msgComments.data.comments.slice(deleteIndexComment + 1)
]
}
}
};
该代码似乎直接改变了状态对象。您已经创建了一个新数组,其中过滤掉了已删除的项目,但您随后直接将新数组分配给 msgCommentsOne.data.comments
。 data
字段与状态中已有的字段相同,因此您直接修改了它。要正确地不可变地更新数据,您需要创建一个新的 comments
数组、一个包含评论的新 data
对象、一个包含数据的新 msgComments
对象和一个新的 state
包含 msgComments 的对象。一直向上链:)
Redux 常见问题解答在 http://redux.js.org/docs/FAQ.html#react-not-rerendering.
提供了关于此主题的更多信息我在 https://github.com/markerikson/react-redux-links/blob/master/immutable-data.md . Also, there's a variety of utility libraries that can help abstract the process of doing these nested updates immutably, which I have listed at https://github.com/markerikson/redux-ecosystem-links/blob/master/immutable-data.md.
上有许多文章链接,这些文章讨论了不可变地管理普通 Javascript 数据