Reactjs 在React Redux reducer中更新数组对象

Reactjs 在React Redux reducer中更新数组对象,reactjs,redux,Reactjs,Redux,这应该很简单,但我没有找到我想要的简单答案。我有一个减速机: const posts = (state = null, action) => { switch(action.type){ case "PUBLISH_POST": return state; case "UNPUBLISH_POST": return state; default: return postList; } } 我有一个带有ID和状

这应该很简单,但我没有找到我想要的简单答案。我有一个减速机:

const posts = (state = null, action) => {
  switch(action.type){
    case "PUBLISH_POST":
        return state;
    case "UNPUBLISH_POST":
        return state;
    default:
        return postList;
  }
}
我有一个带有
ID
状态的帖子列表。我正在发送我的帖子ID,但无法找出简单地将已单击项目的
状态从0更新为1的逻辑。我已经找到了很多半途而废的解决方案,但它们都显得冗长而丑陋——在这种情况下,实现这一点的最短/最好的方法是什么

示例数据:

{
    id:1,
    user:"Bob Smith",
    content:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vulputate mauris vitae diam euismod convallis. Donec dui est, suscipit at dui vitae, sagittis efficitur turpis. ",
    status:1 
}

假设您的
操作类似于:

{
  type: 'UNPUBLISH_POST',
  payload: {
    id: 1,
    user: 'Bob Smith',
    content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vulputate mauris vitae diam euismod convallis. Donec dui est, suscipit at dui vitae, sagittis efficitur turpis. ',
    status: 1
  }
}
简单地使用它:


一个更通用的解决方案,特别是当状态包含除
posts
数组之外的其他数据时:

const posts = (state = null, action) => {
  const post = state.posts.find(p => p.id === action.payload.id);
  switch(action.type) {
    case "PUBLISH_POST":
      return { ...state, posts: [ ...state.posts.filter(p => p !== post), { ...post, status: 1 } ] };
    case "UNPUBLISH_POST":
      return { ...state, posts: [ ...state.posts.filter(p => p !== post), { ...post, status: 0 } ] };
    default:
      return state;
  }
}

您只需在您的状态上使用spread操作符,它就会按照您想要的方式自动更新

例如:

    import { GET_ALL_PENDING_DATAOPS, CHANGE_DATAOPS_ASSIGNED_TO } from "../Actions/types";
const initialState = {
  requests: null
};
export default function(state = initialState, action) {
  const { type, payload } = action;

  switch (type) {
    case GET_ALL_PENDING_DATAOPS:
      return {
        ...state,
        requests: payload
      };
      case CHANGE_DATAOPS_ASSIGNED_TO:          
        return {
          ...state,      
          requests:payload         
        }
    default:
      return state;
  }
}

我的CHANGE_DATAOPS_ASSIGNED_TO action映射了之前的状态,在我的axios调用中,我更新了一个请求数组中的单个请求对象,因为它返回的是单个对象,而我没有显式返回,因为我使用的是spread,它只更新该对象,而不更新其余的对象

假设您有一个帖子数组,您可以搜索要修改的帖子的ID,然后更新它

您的初始状态:

const initial = {
   posts: [],
}
你的减速机:

case MODIFY_POST:
        return {
            ...state, //Returns the current state
            posts: state.posts.map(post=> post.id === action.id ? // Loop through the array to find the post you want to modify
                { ...post, status: action.status} : post // Copy the post state and then modify it. Else return the same object.
            )
        }
现在,在您的操作中,您可以有两个操作来切换状态:

export const enablePost= (post_id) => {
return {
    type: MODIFY_POST,
    id: post_id,
    status: 1
    }
}
export const disablePost= (post_id) => {
return {
    type: MODIFY_POST,
    id: post_id,
    status: 0
    }
}

你看起来怎么样?这是一组帖子吗?@mersocarlin是的,上面的例子什么是动作负载?谢谢。我必须把“这个”从州里移除。我意识到我不能只做一个切换,而不是两个条件。@MattSaunders不客气。我刚刚注意到您的
状态
默认为
null
。也许将它初始化为一个空数组,这样你就不会有未来的问题:)你也可以考虑使用这个模块以及描述的模式。我想你应该返回
filter(p=>p!==post)
和要更新的帖子?@KerSplosh你完全正确,谢谢。根据你的评论更新了答案。这不会改变帖子数组的顺序吗?@slavlazar是的,会的。如果您需要保持秩序,请使用mersocarlin的解决方案,使用
slice
。感谢您添加答案。你能把你的代码包含在答案中而不是图片中吗?在堆栈溢出时发布代码截图是不好的做法。
export const enablePost= (post_id) => {
return {
    type: MODIFY_POST,
    id: post_id,
    status: 1
    }
}
export const disablePost= (post_id) => {
return {
    type: MODIFY_POST,
    id: post_id,
    status: 0
    }
}