【问题标题】:Delete an item from Redux state从 Redux 状态中删除项目
【发布时间】:2016-10-13 03:36:25
【问题描述】:

如果可能的话,我想知道您是否可以帮助我解决这个问题。我正在尝试从 Redux 状态中删除一个项目。我已将用户通过action.data 单击的项目的ID 传递到reducer。

我想知道如何将action.data 与 Redux 状态中的一个 ID 匹配,然后从数组中删除该对象?我还想知道在删除单个对象后设置新状态的最佳方法?

请看下面的代码:

export const commentList = (state, action) => {
  switch (action.type) {
    case 'ADD_COMMENT':
      let newComment = { comment: action.data, id: +new Date };
      return state.concat([newComment]);
    case 'DELETE_COMMENT':
      let commentId = action.data;

    default:
      return state || [];
  }
}

【问题讨论】:

    标签: javascript arrays reactjs redux


    【解决方案1】:

    对于将状态设置为对象而不是数组的任何人:

    我使用 reduce() 而不是 filter() 来展示另一个实现。但是,如何实现它取决于您。

    /*
    //Implementation of the actions used:
    
    export const addArticle = payload => {
        return { type: ADD_ARTICLE, payload };
    };
    export const deleteArticle = id => {
         return { type: DELETE_ARTICLE, id}
    */
    
    export const commentList = (state, action) => {
      switch (action.type) {
        case ADD_ARTICLE:
            return {
                ...state,
                articles: [...state.articles, action.payload]
            };
        case DELETE_ARTICLE: 
            return {
                ...state,
                articles: state.articles.reduce((accum, curr) => {
                    if (curr.id !== action.id) {
                        return {...accum, curr};
                    } 
                    return accum;
                }, {}), 
            }
    

    【讨论】:

      【解决方案2】:

      在我的情况下,过滤器在没有 () 和 {} 的情况下工作,并且状态已更新

      case 'DELETE_COMMENT':
          return state.filter( id  => id !== action.data);
      

      【讨论】:

        【解决方案3】:

        你可以使用试试这个方法。

        case "REMOVE_ITEM": 
          return {
          ...state,
            comment: [state.comments.filter(comment => comment.id !== action.id)]
          }
        

        【讨论】:

          【解决方案4】:

          你可以使用Object.assign(target, ...sources),把所有与action id不匹配的item都散开

          case "REMOVE_ITEM": {
            return Object.assign({}, state, {
              items: [...state.items.filter(item => item.id !== action.id)],
            });
          }
          

          【讨论】:

          • 扩展运算符是 ES6 语法特性。我不确定您为什么在此示例中同时使用 Object.assign。
          【解决方案5】:

          只需过滤 cmets:

          case 'DELETE_COMMENT':
            const commentId = action.data;
            return state.filter(comment => comment.id !== commentId);
          

          这样您就不会改变原始的 state 数组,而是返回一个没有元素的新数组,它的 id 为 commentId

          为了更简洁:

          case 'DELETE_COMMENT':
            return state.filter(({ id }) => id !== action.data);
          

          【讨论】:

          • 我看到了另一个仅使用 id 的示例,而不是您的答案 ({ id })。这里有什么不同?
          • @MattSaunders ({ id }) => ... 是一个 lambda 表达式(js 术语中的箭头函数),它解构了它的参数。这意味着输入应该是一个对象,我们只对它的id 属性感兴趣。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
          • 如果我更改了对象数组中的数组中的对象,该怎么办。 lists: [{name: 'xyz', cards: [{...}]}...many more lists]
          • 不 .filter() 返回一个新数组,因此重新分配应用程序的整个状态?
          • @Shah 这就是 redux 的重点。每次调用 reducer 时都会返回一个新状态,而不是改变现有状态。过滤器不会克隆数组内部的内容,而只会克隆数组结构本身。因此,如果数组中有复杂的对象,它们将保持不变,只需放入一个新数组即可。
          猜你喜欢
          • 1970-01-01
          • 2020-12-15
          • 1970-01-01
          • 2018-05-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-15
          相关资源
          最近更新 更多