我正在更新我所做的“留言板”项目(Brad Traversy的MERN堆栈课程)以包含喜欢的评论。举个简单的例子,想想Facebook:您创建一个人们喜欢的帖子,人们可以发表评论,也可以被喜欢。
我有一个“发布”状态,其中包含帖子赞(post.likes数组),评论(post.comments数组)和评论喜欢(事情比较棘手:嵌套在post.comments数组内部的数组) )。
如何在我的reducer中更新嵌套数组,以便我的页面正确重新渲染?现在,它会记录操作并在手动重新加载页面时显示新的点赞/不喜欢,但不会重新加载页面本身。
我尝试过更新状态,但是现实是,我不确定如何遍历和更新深层嵌套的内容。
这是我的实际职位状态,由Redux DevTools提供。
post: {
posts: [],
post: {
_id: '5cebd8bcdc17fd5cd7e57a45',
text: 'This is my brand new post.',
name: 'Bobby Smith',
avatar: '//www.gravatar.com/avatar/414868368393e3ba8ae5ff93eeb98de6?s=200&r=pg&d=mm',
user: '5cd646c9a632b51373121995',
likes: [
{
_id: '5cebd8d1dc17fd5cd7e57a47',
user: '5cd36ce5fda120050ee64160'
}
],
comments: [
{
date: '2019-05-27T12:32:16.172Z',
likes: [ /*-------- This ---------*/
{
_id: '5cebd8e1dc17fd5cd7e57a48',
user: '5cd646c9a632b51373121995'
}
],
_id: '5cebd8d0dc17fd5cd7e57a46',
text: 'And this is my brand new response.',
name: 'John Doe',
avatar: '//www.gravatar.com/avatar/b2b146dba9e0023cb56637f0df4aa005?s=200&r=pg&d=mm',
user: '5cd36ce5fda120050ee64160'
}
],
date: '2019-05-27T12:31:56.598Z',
__v: 3
},
loading: false,
error: {}
}
}
减速器:
const initialState = {
posts: [],
post: null,
loading: true,
error: {}
}
export default function(state = initialState, action) {
const { type, payload } = action
switch (type) {
case UPDATE_COMMENT_LIKES:
return {
...state,
post: { ...state.post, comments: ???? }
}
default:
return state
}
}
先传递帖子ID和用户ID,然后根据它们是否已存在进行过滤。为了清楚起见,我还将添加动作创建者。
// Add like to comment
export const addCommentLike = id => async dispatch => {
try {
const res = await axios.put(`/api/posts/comment/like/${id}`)
dispatch({
type: UPDATE_COMMENT_LIKES,
payload: { id, likes: res.data }
})
} catch (err) {
dispatch({
type: POST_ERROR,
payload: { msg: err.response.statusText, status: err.response.status }
})
}
}
// Remove like from comment
export const removeCommentLike = id => async dispatch => {
try {
const res = await axios.put(`/api/posts/comment/unlike/${id}`)
dispatch({
type: UPDATE_COMMENT_LIKES,
payload: { id, likes: res.data }
})
} catch (err) {
dispatch({
type: POST_ERROR,
payload: { msg: err.response.statusText, status: err.response.status },
loading: false
})
}
}
现在,它正在更新数据库中的所有内容,但不是立即更新状态并触发重新渲染。
我将尽一切帮助。
谢谢!
答案 0 :(得分:1)
我知道为时已晚,但可能对某人有所帮助。我也曾经做过这门课;) 因此,在您的情况下,减速器将如下所示:
case UPDATE_COMMENT_LIKES:
return {
...state,
post: {
...state.post,
comments: state.post.comments.map((comment) =>
comment._id === payload.id
? { ...comment, likes: payload.likes }
: comment
)
},
loading: false
};
答案 1 :(得分:0)
如果您还要在化简器中拆分删除/添加逻辑,那会更好:
ADD_COMMENT_LIKES
-将喜欢添加到嵌套的喜欢数组REMOVE_COMMENT_LIKES
-将按其ID过滤所选内容export default function(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case ADD_COMMENT_LIKES:
return {
...state,
post: {
...state.post,
comments: [
...state.post.comments,
likes: [
...state.post.comments.likes,
payload <--- inserting the new like
]
]
}
}
case REMOVE_COMMENT_LIKES:
return {
...state,
post: {
...state.post,
comments: [
...state.post.comments,
likes: [
...state.post.comments.likes.filter((item) => item.id !== payload.id)
]
]
}
default:
return state
}
}
阅读如何combine reducers,并将您的状态形成为一个独立的分支。它将帮助您将减速器构造为更具可维护性的结构。