Tags:  reactjsredux
Source:  Twitter logo

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, ? };

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>
);
14 users liked answer #0dislike answer #014
Chris Ngo profile pic
Chris Ngo

You can try replacing the state's array.

case DELETE_ITEM: {
 return {...state. items: state.items.splice(item.index, 1)};
}
7 users liked answer #1dislike answer #17
Isaac Khoo profile pic
Isaac Khoo

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 };
3 users liked answer #2dislike answer #23
Jee Mok profile pic
Jee Mok

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).