4

I have a state in Redux that currently renders like this:

Before click:

{0: {
    open: false,
    negation: false,
    close: false
    },
1: {
    open: false,
    negation: false,
    close: false,
    bool: "and"
    }
}

After click:

{0: {
    open: false,
    negation: false,
    close: false
    },
1: {}
}

I'd like to completely remove the key 1 (in general it's [action.id]).

Currently the cases in the reducer are:

case 'HANDLE_INCREASE_CHANGE':
  return {
    ...state,
    index: state.index + 1,
    [state.index + 1]: {
      open:false,
      negation: false,
      close: false,
      bool: 'and'
    }
  }
case 'HANDLE_DECREASE_CHANGE':
  return {
    ...state,
    index: state.index - 1,
    [state.index]: {}
  }

The wrong part is:

[state.index]: {}

Can you help me please? thanks a lot!

SkuPak
  • 307
  • 8
  • 16
  • Does this answer your question? [How do I remove a property from a JavaScript object?](https://stackoverflow.com/questions/208105/how-do-i-remove-a-property-from-a-javascript-object) – Brian Thompson Jan 24 '20 at 15:41

3 Answers3

8

You should just be able to call delete state[action.id]. Although as you're in a reducer function, you should take a copy of the state first, delete from that, then return the copied version.

case: 'HANDLE_DECREASE_CHANGE':
  const next = {...state}
  delete next[action.id]
  return next
Matt Sugden
  • 844
  • 6
  • 12
  • 1
    Its already a copy, so you could just return `next` instead of destructuring to create a third object, but good answer. – Brian Thompson Jan 24 '20 at 15:30
  • That's true, you don't want to mutate `state`, but you made a copy of it by doing `const next = {...state}`. So all I'm saying is technically you could just do `return next` – Brian Thompson Jan 24 '20 at 15:39
  • 1
    @BrianThompson You're absolutely right. I've updated my answer accordingly. It was a force of habit always writing return {...} in reducers. I actually misread your original comment, which is why I deleted my reply, as it didn't make any sense – Matt Sugden Jan 24 '20 at 15:40
  • This breaks the `no-case-declarations` ESLint rule. – Audiopolis Oct 20 '21 at 20:19
2

You are setting new properties to state object, to remove then you need to use delete. Remember to make a copy of the current sate first.

case: 'HANDLE_DECREASE_CHANGE':
  let nextState = {...state}
  delete nextState[propToDelete]
  return nextState

I believe it would be best to have an array of elements and not set properties directly to the sate object.

const iniitalState = {
 index: 0,
 elements: []
}

case 'HANDLE_INCREASE_CHANGE': {
  state.elements.push({
    open:false,
    negation: false,
    close: false,
    bool: 'and'
  })
  return {...state, index: state.index + 1, elements: [...state.elements] }
}
case 'HANDLE_DECREASE_CHANGE': {
  let newElements = [...state.elements]
  newElements.splice(action.indexToRemove, 1) // Removes Element

  return {...state, index: state.index - 1, elements: [...newElements] }
}
Lucas Fabre
  • 1,806
  • 2
  • 11
  • 25
1

delete the key you want removed:

const resultingState = {...state, index: state.index - 1}
delete resultingState[state.index]
return resultingState

or extract it away with rest parameters:

const {...extractedState, [state.index]: ignored} = state
return {...extractedState, index: state.index - 1}
Badashi
  • 1,124
  • 9
  • 18