Search code examples
javascriptecmascript-6reduxecmascript-5

Mapping Redux reducers to unknown keys in State


According to the Redux docs, normalizing state is the best way to approach data structures on the front end. The example they give is below:

{
  posts : {
    byId : {
        "post1" : {
            id : "post1",
            author : "user1",
            body : "......",
            comments : ["comment1", "comment2"]    
        },
        "post2" : {
            id : "post2",
            author : "user2",
            body : "......",
            comments : ["comment3", "comment4", "comment5"]    
        }
    },
    allIds : ["post1", "post2"]
  },
  comments : {
    byId : {
        "comment1" : {
            id : "comment1",
            author : "user2",
            comment : ".....",
        },
        "comment2" : {
            id : "comment2",
            author : "user3",
            comment : ".....",
        },
        "comment5" : {
            id : "comment5",
            author : "user3",
            comment : ".....",
        },
    },
    allIds : ["comment1", "comment2", "comment5"]
  }
}

How would one go about writing reducers in such a way that the id of the post or comments can be dynamically set as the key.


Solution

  • I'm not sure (because the question is not very clear), but I think you want to use computed property names when returning a new object literal from the reducer:

    projectsReducers (state={}, action) {
        // Ensure that the projectName is actually accessible
        if (!action || !action.projectName) {
            return state;
        }
    
        // Retrieve the project name dynamically
        const projectName = action.projectName;
    
        return {
            // Preserve the previous state by spreading all of it's properties
            // please note that Object spread is still a Stage 3 proposal for ECMAScript,
            // so transpilation might be required
            ...state,
    
            // Assign current project's new state
            [projectName]: singleProjectReducer(
                state[projectName],
                action
            )
        };
    }