I am working on an web app where user can subscribe to available features and all those features are having certain effects on user actions. I am using redux thunk for async actions.
eg. user can select product to buy or sell from product list, this triggers a reducer called userIntention and after that createProductForm reducer is called which displays product form along with product information. User can subscribe to feature like recommendation, best deals, etc. which can modify certain parameters of product properties like tags, price. I want to implement this in such a way that if createProductForm is triggered that reducer will collect data from recommendation, best deals, etc dynamically and based on there results, it'll form user product form.
We want to keep multiple developers to work on different features without conflicting with other's features and codebase. So that when a new feature is developed, we don't have change core logic.
But this has to happen without prior knowing which reducers to call for creatingProductForm, it could be none or many feature reducers.
It's like plugin, where subscribe activates some reducers and middlewares.
Which one is best for this case : reducer or middleware ? I've tried adding dynamic middlewares, dynamic reducers but both of them are having their own pitfalls.
What i've tried:
- After feature subscription, action called 'ENABLE_FEATURE' is dispatched to which feature reducers can listen register themselves dynamically. But i am finding it difficult to maintain which reducers to call. Is there any way to keep listing reducers in redux store.
- same tried with middlewares, but then dynamically removing one of the middlewares is too complicated.
- create my own utility outside redux, where registration, subscription of dynamic reducers is implemented, but then how to call reducers from outside react component since dispatch and store is unavailable.
We're using rekit studio for development.
EDIT
This is my application architecture. As you can see, all features are developed independent of each other along with reducers, store, components.
What we need is once f-core component is developed it's untouched even if we implement new features independent of it. Somewhat like a registry where features can register themselves so f-core comes to know about their existence. Then this features should've exposed some functions ( reducers ) which will be decided at runtime.
Application architecture
/node_modules
package.json
package-lock.json
/public
/src
- /common
- configStore.js
- history.js
- rootReducer.js
- routeConfig.js
- /features
- /f-core
- component1.js
- component1.less
- index.js
- route.js
- /api-service
- router.js
- constants.js
- service.js
- /redux
- actions.js
- constants.js
- reducer.js
- initialState.js
- reducer1.js
- /f1
- component1.js
- component1.less
- index.js
- route.js
- /api-service
- router.js
- constants.js
- service.js
- /redux
- actions.js
- constants.js
- reducer.js
- initialState.js
- reducer1.js
- /f2
- component1.js
- component1.less
- index.js
- route.js
- /api-service
- router.js
- constants.js
- service.js
- /redux
- actions.js
- constants.js
- reducer.js
- initialState.js
- reducer1.js
- index.js
- Root.js