Search code examples
reactjsreduxselectorreselect

Redux Selector for normalized state


I need help in creating the selectors for the state which is normalized based on the documentation from redux docs

State

{
    "entities": {
        "people": {
            "byId": {
                "1": {
                    "name": "Test User 1",
                    "classes": ["class1", "class2"],
                    "isSelected": true
                },
                "2": {
                    "name": "Test User 2",
                    "classes": ["class2", "class3"],
                    "isSelected": false
                },
                "3": {
                    "name": "Test User 3",
                    "classes": ["class4"],
                    "isSelected": false
                }
            },
            "allIds": ["1", "2", "3"]
        },
        "classes": {
            "byId": {
                "class1": {
                    "name": "Class 1",
                    "courses": ["course1", "course2"]
                },
                "class2": {
                    "name": "Class 2",
                    "courses": ["course2"]
                },
                "class3": {
                    "name": "Class 3",
                    "courses": ["course1", "course3"]
                }
            },
            "allIds": ["class1", "class2", "class3"]
        },
        "courses": {
            "byId": {
                "course1": {
                    "name": "Course 1"
                },
                "course2": {
                    "name": "Course 2"
                },
                "course3": {
                    "name": "Course 3"
                }
            },
            "allIds": ["course1", "course2", "course3"]
        }
    }
}

On every people's profile, I want to display the associated classes and courses. I am unable to create selectors to get access to this information.

People's Selector

import { createSelector } from 'reselect';

const getPeopleDetails = createSelector(
    state => state.entities.people,
    (people) => people.allIds.reduce(
        (acc, cV) => {  
            if(people.byId[cV].isSelected) acc.push(people.byId[cV]); return acc; 
        }, [])
);

export default {
    getPeopleDetails
}

Since createSelector doesn't accept any parameter. For my slice in state for courses; how can I create a selector where to get information for the current selected people's profile?

Should I create a junction table for to depict the relationship between the entities?

(I am very new to react/redux)


Solution

  • I solved this one by create another state slice called ui. In that slice, I manage the selected object IDs.

    The components are rendered when there is a value in the selected Id for a particular component. Every component has a if condition which checks the the ui slice has the selected IDs populated.

    React Design

    For example,

    {
        "ui": {
            "personSelectedId": ["1"],
            "classSelectedId": ["class1", "class2"],
            "courseSelectedId": ["course1", "course2"],
        }
    }
    

    Hope this makes sense.