0

I am trying to update a nested array filed in redux reducer, here is my array i want to update ( just add updating:true filed ) my array looks like

I want to add a updating:true filed on room object after number filed

items: Array(1)
    0:
    name: (2) [{…}, {…}]
    rooms: Array(2)
        0: {_id: "5d494e5b11b962065632c760", number: "100" …}
        1: {_id: "5d494e6211b962065632c761", number: "102" …}

look like

items :
     [{
        name: [{}],
        rooms : [{}]
     }]

Here is my redux reducer code, i am trying to update

case Constants.Status_ADD_REQUEST:
var ID = ID; // action id

return {...state,
  items:[{...state.items, 
        rooms:[{...state.items.rooms, 
            rooms:{...state.items.rooms.map(x=> x._id === ID ? {...x,updating: true} :  x )}}]
 }]
};

anyway its not working :) please guide me to correct it

Harry Edward
  • 141
  • 2
  • 2
  • 14

1 Answers1

1

Have a second look at the spread Syntax in JavaScript, especially spread for array literals. For example in your reducer, you create a new state with an items array containing only one fix object (it would still be only one object, even if you would add more items in your example). This item object contains your previous converted and spread items array and rooms property - not really your state shape.

How you could create the state instead:

Full example repo (with TypeScript)

const initialState = {...}

function rootReducer(state = initialState, action) {
  switch (action.type) {
    case Constants.Status_ADD_REQUEST:
      return {
        ...state,
        items: state.items.map(item =>
          item.rooms.some(i => i.id === action.id)
            ? {
                ...item,
                rooms: item.rooms.map(room =>
                  room.id === action.id ? { ...room, updating: true } : room
                )
              }
            : item
        )
      };
    default:
      return state;
  }
}

in the style of "Updating an Item in an Array" Redux docs.

If you have to ensure immutable patterns this way and manually, things will get ugly fast. Reason: The key to updating nested data is that every level of nesting must be copied and updated appropriately (structural sharing).

To circumvent those problems, your goal should be to keep your state flattened and to compose reducers. If cloning your state still becomes too complex, you could make use of Immutable Update Utility Libraries. I personally can recommend immer, as you can change state in a mutable way, while the library takes care of deep clones/structural sharing via JavaScript proxies transparently.

PS: It could also make sense to think of another name for "update room", if it is some of your domain/app data.

ford04
  • 66,267
  • 20
  • 199
  • 171