Automating Store and Action registration for multiple components using Fluxxor
While fluxxor provides a tonne of useful features, one of the things that I found lacking was the ability for components register the stores that they depend upon dynamically.
It is very likely that when architecting your flux application, you will organize your components into different folders. Some of these components will depend on stores and actions. And for some of them, the stores and actions are shared.
The quick start guide shows you how you register actions and stores beforehand. Although its an effective strategy, its not scalable because it is difficult to identify all the stores and actions that the sub-components on a page are going to require at the time of defining the top level component, the place where your instantiate your flux object. This also implies that you would have to edit your top level component to register a new store whenever a component is added that depends on a store.
The situation gets even more complicated if you allow components to register stores by themselves at runtime because it is possible that different components might depend same store and therefore it is wise to only have one place to register a store.
If only we could have a way to allow each component to mention the stores it depends on, and then the runtime would take care of registering them if not already registered.
It seems like this is a very good use case for creating a mixin that can act as a checkpoint for components that need to register stores and actions.
Lets say that we have a simple data store as shown below.
And a simple action as shown below
Notice that in the last line, we assigned a displayName to the store. This is the name with which we will auto-register the store using our mixin.
We will call our mixin
FluxContextMixin since it helps in constructing the flux context by adding stores and actions as necessary.
Our objective is to use this mixin on any component that depends on other Fluxxor stores and actions. And by simply listing out the stores and actions in the statics, the mixin would automatically register them in the flux context if they were not already registered.
Below is an example of a component that would use our
Now comes the meat of the matter, our FluxContextMixin itself. I have added a tonne of inline comments to explain what I am trying to do at each step of the way.
Essentially, the mixin does a few things
- Defines a lifecycle method the getInitialState,
- Within this method, it inspects the statics array of stores and actions.
- For each store that it finds, it attempts to register it. It does so by checking the store constructor has already been registered. If no, it registers the store with the flux context, saves a reference to the constructor in its closure scope and then adds the name to the registered store list.
- Actions are simpler since they essentially need to be unique within the flux context and are nothing more that than key value pairs of action names and function handlers. In our case, we simply add the action and its handler to the closure scope if the action name is not already registered.
After using this mixin for a while now, building components is a snap since all you gotta do is list the dependencies. As far as instantiating stores with a config is concered, you can do it at any time on the require. However, since stores are meant to be used by multiple components, they would ideally be instantiated with the same config everywhere but its only one component in the component tree actually registers the instance with the flux context.