I
I
Igor Shumilovsky2016-03-02 17:21:12
React
Igor Shumilovsky, 2016-03-02 17:21:12

What is the best way to organize a reducer in Redux?

Hello! Tell me how best to organize the structure of the reducer (s), if I need to display such a tree:
root
--array1:
----[0]: { id: 1, elements: [1,1,1,1] }
-- --[1]: { id: 2, elements: [1,1,1,1] }
----[2]: { id: 3, elements: [1,1,1,1] }
To the reducer actions will come as if adding elements to array1. and on adding elements to elements.
What is the best way to organize it? Move elements to a separate reducer? Could you also show me how to add an element to elements in this case?
Is this option correct?

case ADD_ELEMENT:
    var array2 = state.array1;
    array2[arrayIndex].elements.push({
      name: action.name
    })
    return {
      ...state,
      array1: [...array2],
    }

Answer the question

In order to leave comments, you need to log in

1 answer(s)
N
Nikita Gushchin, 2016-03-03
@JiSeven

As far as I understood you have two entities (one is root and one is in elements). Then it is better to store this case in a normalized state: there are two reducers for cases, each works with its own entity, and we denormalize in the selector. At the same time, it is more convenient to store entities as an { id: entity } object, and not as an array.

// rootEntity reducer
const initialState = {
  entities: {}
}

function rootEntityReducer(state = initialState, action = {}) {
  switch(action.type) {
    case ADD_ELEMENT:
      const { targetEntityId, element } = action.payload
      const targetEntity = state.entities[targetEntityId]
      return {
        ...state,
        entites: {
          ...state.entities,
          [targetEntityId]: { ...targetEntity, elements: [ ...targetEntity.elements, element ] }
        }
      }
    default:
      return state
  }
}

UPD1 if entities is an array
// rootEntity reducer
const initialState = {
  entities: []
}

function rootEntityReducer(state = initialState, action = {}) {
  switch(action.type) {
    case ADD_ELEMENT:
      const { targetEntityId, element } = action.payload

      return {
        ...state,
        entites:  state.entities.map(
          entity => entity.id !== targetEntityId
            ? entity
            : { ...entity , elements: [ ...entity.elements, element ] }
        )
      }
    default:
      return state
  }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question