0

I have a fairly complex/nested redux store like this:

{
  object1
  {
    array:
    [
      object[1]: {
        id: 1,
        replace: ""
      }
      object[2]: {
        id: 2
        replace: ""
      }
      object[3]: {
        id: 3,
        replace: ""
      }
    ]
  }
}

After dispatching an action, I need to insert the action to one of the object[] based on ID. I am currently using the following scripts to update replace within the reducer. However this will change the array to an object due to the curly bracket of object2: {}.

case UPDATE:
  return {
    ...state,
    object1: {
      ...state.object1,
      array: {
        ...state.object1.array,
        [action.id]: {
          ...state.object1.array[action.id],
          replace: action.result
        }
      }
    }
  };

My render will breaks after that since object2.map is no longer a function after changing to object. How do I workaround this without converting it to an object?

The following will failed with syntax error:

case UPDATE:
  return {
    ...state,
    object1: {
      ...state.object1,
      array: [
        ...state.object1.array,
        [action.id]: {
          ...state.object1.array[action.id],
          replace: action.result
        }
      ]
    }
  };
Yen Sheng
  • 695
  • 1
  • 12
  • 28

3 Answers3

1

You cannot directly specify the index that you want to modify with spread syntax, you need to first find the index and do it like

case UPDATE:
  var idx = state.object1.object2.findIndex(obj => obj.id === action.id)
  return {
    ...state,
    object1: {
      ...state.object1,
      object2: [
        ...state.object1.object2.slice(0, idx),
        {
            ...state.object1.object2[idx],
            replace: action.result 
        }
        ...state.object1.object2.slice(idx + 1)
      ]
    }
  };

Or else you can make use of immutability-helper package. See this answer for a sample of how to do it

how to use Immutability helper to update a nested object within an array?

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
1

'You can check the library immutadot. Its purpose is to help update complex nested data structure in a very concise way and was created with redux usage in mind.

In your case you can write it this way :

import { set } from 'immutadot'

...

  case UPDATE:
    return set(state, 'object1.arrary[' + id + '].replace', action.result)
    // or with templated string
    return set(state, `object1.arrary[${ id }].replace`, action.result)

...

It relies on lodash under the wood so you can use all faculties of lodash's functions.

Emrys Myrooin
  • 2,179
  • 14
  • 39
0

Following code for using immutability-helper package.

case UPDATE:
  return update(state, {
    object1: {
      array: {
        [action.id]: {
          replace: {
            $set: action.result
          },
        },
      },
    }
  });
Yen Sheng
  • 695
  • 1
  • 12
  • 28