The Idea behind Angular is Reusable components, but reducers are functions and hence can’t be duplicated.
For instance if there is a dropdown filter that has a dropdown reducer and a dropdown state in the store (having name and options props), then if the same filter is used for displaying user list filter and age filter, then we’ll need to design the component and it’s reducer to accommodate for cloning scenarios.
There are 3 main ways to design this:
- SINGLE COMPONENT REDUCER (recommended for dynamic filters)
- Have a single reducer for the dropdown filter (and separate for date filter etc)
- The state in this case will be an array of dropdown filters, that this single reducer will be responsible for.
- The ACTION will have either:
- TYPE IDENTIFIER:
- See createCounterWithNamedType (or it’s generic version createFilteredReducer) here
- Eg. APPLYFILTER_A to denote that this action should apply to Filter A only
- PAYLOAD IDENTIFIER:
- Action Payload will have identifier(ID/Name etc.) and that’s how the reducer will know which filter in the array to reduce.
- See createCounterWithNameData (or it’s generic version createFilteredReducer) here
- This proposes the solution to reducer reuse by using either action type or payload identifier. Using the payload approach (which we’re using too), it solves the problem exactly like we solved it, but uses a higher order function (with identifier closure) instead of the class based approach that we were trying the other day which didn’t work coz of this reference issue. The generic higher order reducer (createFilteredReducer) is quite elegant coz it takes a predicate so works for either identifier.
- TYPE IDENTIFIER:
- SINGLE GIANT REDUCER (recommended for predefined filters)
- Have a single filter reducer for ALL filters (dropdown, dateTime etc.) irrespective of their cloning state.
- The state in this case will be an array of dropdown filter objects (user, age etc.), that this single reducer will be responsible for.
- The actions that any filter will dispatch will have the filter identifier (ID/Name etc.) and that’s how the reducer will know which filter in the array to reduce.
- SEPARATE REDUCER (not recommended)
- We can also have a separate reducer for each clone of the component, and the logic for all actions can be abstracted out of the user and age reducer functions hence preventing code duplication in the user and age filter reducers.
- Collate Actions
- Have a filter reducer and have all filters provide their actions that will be collated into the filter reducer at runtime
- COMBINE REDUCERS
- Here Create a runtime combine reducer function that looks like this: