The store has the following responsibilities:
- Holds application state;
- Allows access to state via
getState()
; - Allows state to be updated via
dispatch(action)
; - Registers listeners via
subscribe(listener)
.
createStore(
DecoratedModel,
[storeEnhancer]
)
import { createStore } from 'modulajs';
import Model from './model.js';
const store = createStore(Model);
function handleStoreChanged() {
console.log("Store has changed. The new state is:", store.getState());
}
// subscribe to store changing
store.subscribe(handleStoreChanged);
// unsubscribe
store.unsubscribe(handleStoreChanged);
The third parameter is a store enhancer. You can use compose
to merge several enhancers into one.
The following example applies redux-thunk
and devToolsExtension
to your store.
import { createStore } from 'modulajs';
import { applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk'
import Model from './models';
const store = createStore(
Model,
compose(
applyMiddleware(thunk),
window.devToolsExtension ? window.devToolsExtension() : f => f
)
);
If an enhancer is provided, the createStore
function becomes enhancer(createStore)(DecoratedModel)
. In this way, enhancer
is able to control everything happening in the store: from creating store to handling actions and updating the state.
Middlewares are restricted enhancers: they can control state updating and action handling but do not have access to store creating. Middlewares are enough for most use cases.
applyMiddleware
can turn middlewares into an enhancer.
ModulaJS borrow the ideas of enhancers and middlewares from Redux, and its interface is designed to be compatible with Redux. So it's safe to use most redux middlewares in ModulaJS projects. You can also read Redux docs: Middlewares to get better understanding of middlewares.