Redux Modules Enhancer
IMPORTANT NOTICE
Experimental I didn't realise publishing this package to NPM would cause so many downloads. This package is still experimental so I would not currently recommend it for production use yet though I intend for it to production ready in the coming days.
Some middleware may not work with this library as all actions are pushed through each middleware in each module, so some middleware may not handle this scenario gracefully, though thunks and redux-observable have been tested.
Motivation
Having to compile a list of possible reducers, state and/or middleware ahead-of-time is error prone (you forget to add a reducer/middleware) and time consuming (hunting down which reducers and middleware you need).
This was partially alleviated by grouping items together using Redux Modules (aka ducks) but they would still need to be known ahead-of-time.
Why not use another module injection module?
This module is less invasive and requires less code changes (none?) compared to other module injection solutions.
How to add it to my store?
Easy, just like any other enhancer,
var Redux = ; var modulesEnhancer = ; var store = Redux;
or, if you want to use other enhancers as well,
var store = Redux;
What does the enhancer do?
The enhancer adds three methods to the store returned when calling createStore,
store;
or
var module = moduleId reducer initialState middleware store;
Adds a module using the given reducer, initialState and middleware.
- moduleId - (Required) this is equivalent to the name of the state object for a reducer when using combineReducers.
- reducer - (Required) - this is the reducer that will run on the state for this module.
- initialState - (Default: {}) this is the initialState that will be set for the module .
- middleware - (Default: None) An array of middleware objects (store.getState() will return the root state, not the module's state, to get the module's state use store.getState()[moduleId])
store
or
var module = moduleId ... ;store;
Removes a module that has already been added.
- moduleId - (Required) this is equivalent to the name of the state object for a reducer when using combineReducers.
var moduleAlreadyAdded = store
or
var module = moduleId ... ;var moduleAlreadyAdded = store;
Returns true if a module with the given moduleId already exists OR if a base reducer or the initial state added a key to the root state with the same name, otherwise false.
- moduleId - (Required) this is equivilent to the name of the state object for a reducer when using combineReducers.
Examples
var store = Redux;store; var myModule = moduleId: "my-module" reducer: myModuleReducer initialState: myModuleInitialState middleware: myModuleMiddleware1 myModuleMiddleware2; store;store; // Received by myInitialReducer (and any other enhancers), as well as the module's myModuleReducer.store;store; // Only received by myInitialReducer (and any other enhancers), actions are no longer dispatched to your module reducer or middleware, and the state will have been removed.
Using React.js?
Why not check out my other project, react-redux-module that allows you to add,
or
var myModule = moduleId: "my-module" reducer: myModuleReducer initialState: myModuleInitialState middleware: myModuleMiddleware1 myModuleMiddleware2; ... <ReduxModule module=myModule />
anywhere that a component requires a module, so the module is added (if not already added).
Recommended module structure
The following is a template to use when creating your own modules,
;; // Action Typesconst DO_MORE_STUFF = myLibraryNs + "DO_MORE_STUFF";const DO_STUFF = myLibraryNs + "DO_STUFF"; const publicActionTypes = DO_STUFF // Action creators + thunksconst doMoreStuff = { return type: DO_MORE_STUFF otherStuffToDo };const doStuff = { return type: DO_STUFF thingsToDo };const getStuff = ; const publicActions = doStuff getStuff; // Reducerconst reducer = { }; const actions = publicActions;const actionTypes = publicActionTypes; // Module factory { const initialState = stuffToDo: ; const middleware = thunk ; return moduleId reducer initialState middleware actions actionTypes }
If you intend to use the same namespace in multiple files, keeps your namespaces in a separate redux-namespaces.json file,
"myLibraryNs": "http://www.example.com/myLibrary/"