0

I have the following case inside of my reducer. It is triggered when a user answers a question. When a user answers a question, it need to be removed from a nested array.

Example question object (these are in an array)

{
    "title": "Quick Questions",
    "questions": [
        "title": "Hello?"
        "answers" [ /*... array of answers in here */ ]
    ]
}

My reducer case

case ANSWER_QUESTION:
    // The 0s here would be dynamically populated
    state.questionGroups[0].questions.splice(0, 1)

    return Object.assign({}, {
        ...state,
    })

However, here I am directly manipulating the state, which I know is incorrect and will cause redux to not update the states correctly to get my components to rerender.

What is the correct way to do this?

EDIT: This may or may not be the reason my component isnt re-rendering. That might be to do with the fact that using connect() only applies shallow comparisons, is that correct?

Aleski
  • 1,402
  • 5
  • 16
  • 30
  • Possible duplicate of https://stackoverflow.com/questions/34582678/is-this-the-correct-way-to-delete-an-item-using-redux – Prasun May 02 '18 at 14:44

3 Answers3

0

First: You are using Splice method which is actually a mutable method. You should use Slice instead.

Second: If you need to manipulate the state, you should edit a copy of it.

Like this:

const newState = state;

// here you edit your stte
newState = newState.questionGroups[0].questions.slice(0, 1)

// here you return your new state
return Object.assign({}, {
    ...newState,
})

Hope it helps

Sergio
  • 1,370
  • 11
  • 12
0

First copy the state, then manipulate and return.

case ANSWER_QUESTION:
  var newState = Object.assign({}, state);
  //make your manipulations here
  return newState;
acbay
  • 832
  • 7
  • 7
0

Every time you should return a new object. You can use ES6 features for this easily.

case ANSWER_QUESTION:
        return {
            ...state,
            questionGroups[0]: [...state.questionGroups[0].questions.slice(0, action.payload), ...state.questionGroups[0].questions.slice(action.payload + 1)]
    }
csath
  • 1,248
  • 11
  • 25
  • This is what i was originally trying to do, however when I write `questionGroups[0]` visual studio code complains at me, saying `expected ":"` – Aleski May 03 '18 at 08:04