travelboy
travelboy

Reputation: 2697

Delete key from immutable object (redux state)

I'm writing a redux reducer to delete a key from a state object:

state = {
  items: {
    key1: {foo: 'bar'},
    key2: {foo: 'baz'}
  },
  someOtherKey: 'value'
}

My reducer:

function reducer(state, action) {
  if (action=='DEL') {
    return {
      ...state,
      items: {
        ...state.items,
        [action.key]: undefined
      }
    }
  }
}       

I expected that this would return a new state with the respective property deleted, but instead it returns a new state with the key still present in the object but having the value undefined.

Is there an elegant way in ES6 to write such a reducer? I guess I could use Object.assign and delete the property, but the above pattern is so much more expressive, so I'd like to write it this way if possible.

Upvotes: 0

Views: 6066

Answers (3)

strager
strager

Reputation: 90022

Another technique: copy the object then delete the key:

function reducer(state, action) {
  if (action=='DEL') {
    let newItems = {...state.items};  // Copy the object
    delete newItems[action.key];      // Remove key from the copy
    return {
      ...state,
      items: newItems,
    };
  }
}

Upvotes: 1

William Bernting
William Bernting

Reputation: 571

Untested, what about this? It will create a shallow copy (immutable) of each item, except the one you don't care for.

function reducer(state, action) {
    if (action == 'DEL') {
        return {
            ...state,
            items: Object.keys(state.items).reduce((obj, key) => {
                if (key !== action.key) {
                    obj[key] = { ...state.items[key]
                    }
                }
            }, {})
        }
    }
}

Upvotes: 1

travelboy
travelboy

Reputation: 2697

I ended up using the lodash function omit:

import { omit } from 'lodash'

function reducer(state, action) {
  if (action=='DEL') {
    return {
      ...state,
      items: omit(state.items, action.key)
      }
    }
  }
}

The fact that the lodash library contains such a function leads me to the assumption that there is probably no easier way to express the operation in simple JavaScript. If I'm wrong, let me know; I'd be very interested to hear.

Upvotes: 5

Related Questions