Search code examples
dynamickeyredux

Redux Reducer: key injection into state


First, I do understand this is a mutated state change; I know shame on me. Sometimes the correct way doesn't appear to be the smartest or I at least don't know any better.

Let me explain, I wan't to inject keys into my state without creating and exchanging old state and new state for predefined items. I simply want to inject keys for a while and if I don't then they are all cleared anyway. My initial state looks like

{graphSite: {site: "default", graphBrowser: { graphID: '', graphKey:'' }, browsable:[] }};

my reducer looks like this **using babel es7 object spread operator

case BROWSER: { state.graphSite.browsable[action.id] = action.payload
                return {...state}
               }

So this will work but redux dev tools doesnt show the state change though the browsable array is accessible perhaps this is because I went against the grain though if I extend the changes to:

case BROWSER:  { state.graphSite.browsable[action.id] = action.payload
                        return {...state, 
                                graphSite: {...state.graphSite, 
                                    graphBrowser: {...state.graphSite.graphBrowser},
                                    browsable: {...state.graphSite.browsable}   }
                                }
                            }

now browsable shows correctly in the tool, but ideally I these are the same thing.

So the question is what is the best way to manipulate the state for dynamic keys that are not in the initial store state. This works just feels like I'm doing something wrong because I manipulated the original state.


Solution

  • The title confused me in the first place. dynamic key injection sounds way too fancy for me :P.

    Anyway, you actually want to add a new pair to your browserble. You had:

    case BROWSER: { state.graphSite.browsable[action.id] = action.payload
                return {...state}
               }
    

    This is wrong (assuming state comes form reducer parameter), because you are directly modifying the state object.

    One of the principle of redux is that Changes are made with pure functions. (redux docs).

    FTFY:

    case BROWSER: { 
      const nextState = JSON.parse(JSON.stringify(state)); // deep copy your state
      nextState.graphSite.browsable[action.id] = action.payload
      return nextState
    }
    

    This isn't most effecient code, JSONoperations are expensive. It is just to demonstrate the principle of not mutating the state object directly.