6
votes

i wonder how i can delete item with onClick from redux state.

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

then i'm rendering my object with list in my component:

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

and then passing this item to reducer with action.payload

but then i don't know how delete item from state.

eg: action.payload is item which i get at onClick how figure out this here?

case DELETE_ITEM:
      return { ...state, ? };
3
Filter out the item with that id should do the trick - Tony Ngo
If it doesn't have an id, you can always use the index :) - Cool Guy

3 Answers

11
votes

Considering that your state is an array of objects, one solution would be to eliminate the selected item by their index. You should also avoid doing direct state-mutations, in redux as this will lead to side-effects. Always try to create a deep-clone or copy of the state if you plan on doing some sort of mutation (deletion, update). So to cover all the bases:

Your reducer should probably looks something like:

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)
         }
   }
}

In this case, we're just going to setup the action.payload to just be the index of the item instead of entire item.

So your action creator should look like:

export const deleteItem = (index) => {
   dispatch({
      type: DELETE_ITEM,
      payload: index
   })
}

And now we can really simplify your mark-up. Simply use the index parameter in .map() as to satisfy the argument of our action-creator.:

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

You can try replacing the state's array.

case DELETE_ITEM: {
 return {...state. items: state.items.splice(item.index, 1)};
}
3
votes

after spreading the current state, update the items by filtering it out of a unique property (eg: id):

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