如何从redux状态中删除项目?

12

我想知道如何通过onClick从redux状态中删除项目。

let initialState = {
  items: [
      {
       name: 'A',
       age: 23
      },
      {
       name: 'B',
       age: 20
      },
      {
      name: 'C',
      age: 29
      }
     ]
    }

然后我在我的组件中使用列表渲染我的对象:

const listItems = this.props.MyState.items.map((item) =>
  <li key={item.name} onClick=event => this.props.deleteItem(event, item) >{item.name}</li>
);

然后将该项与 action.payload 一起传递给 reducer,但是我不知道如何从 state 中删除该项。

例如:action.payload 是我在 onClick 获取的项,我应该如何在这里找到它并将其删除?

case DELETE_ITEM:
      return { ...state, ? };

过滤掉具有该ID的项目应该解决问题。 - Tony Ngo
如果没有ID,您总是可以使用索引 :) - Chris Ngo
3个回答

18

考虑到您的状态是一个对象数组,一种解决方法是通过它们的索引来消除所选项目。在Redux中,应避免直接进行状态变化,因为这会导致副作用。如果您计划进行某种变异(删除,更新),请始终尝试创建状态的深度克隆或副本。因此,为了涵盖所有情况:

您的reducer应该大致如下:

let initialState = {
  items: [
      {
       name: 'A',
       age: 23
      },
      {
       name: 'B',
       age: 20
      },
      {
      name: 'C',
      age: 29
      }
  ]
}

const userReducer = (state = initialState, action) => {
   switch(action.type){
      case ADD_ITEM:
         ...
      case DELETE_ITEM:
         return {
           ...state,
           items: state.items.filter((item, index) => index !== action.payload)
         }
   }
}
在这种情况下,我们只需要将action.payload设置为项目的索引,而不是整个项目。

因此,您的操作创建者应如下所示:
export const deleteItem = (index) => {
   dispatch({
      type: DELETE_ITEM,
      payload: index
   })
}

现在我们可以真正简化您的标记。只需使用.map()中的index参数即可满足我们操作创建器的参数。

const listItems = this.props.MyState.items.map((item, index) =>
  <li key={item.name} onClick={() => this.props.deleteItem(index)} >{item.name}</li>
);

7
您可以尝试替换状态数组。
case DELETE_ITEM: {
 return {...state. items: state.items.splice(item.index, 1)};
}

3

在传播当前状态之后,通过筛选具有唯一属性(如: id)的项来更新items

case DELETE_ITEM:
      return { ...state, items: state.items.filter(i => i.id !== action.payload.id };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接