flux-stores-pool
v1.1.0
Published
Solution to manage Flux stores
Downloads
16
Readme
Please, update your instances of flux-stores-pool to ^1.1.0
FluxStoresPool
Solution to create, destroy, register and unregister your Flux stores any moment you wish. Also it allows to resolve "dispatch inside dispatch" problem - to reinit your store you can remove and then create it even inside a dispatched callback.
Installation
$ npm install flux-stores-pool
Usage
import FluxStoresPool from 'flux-stores-pool';
...
/*
create a store
MyStoreClass should extends a FluxStore - ReduceStore, f.e.
*/
FluxStoresPool.create('MyStoreID',MyStoreClass);
/*
OR a bit more advanced (from v.0.4.0):
*/
FluxStoresPool.create('MyStoreID',MyStoreClass, myParam1, myParam2);
/*
parameters will be passed to MyStoreClass constructor:
new MyStoreClass(myParam1,myParam2)
*/
/*
destroy store
*/
FluxStoresPool.remove('MyStoreID');
/*
IMPORTANT NOTE!
After you create or remove stores - it would be wise to connected/disconnect them to your container(s).
*/
FluxStoresPool.reBind(yourContainerObject, yourContainerClass);
/*
but if you create stores inside component's constructor or remove them inside componentWillUnmount -
reBinding isn't required.
See examples/advanced sample.
*/
/*
switch store off
the store will keep all it's data, but won't receive actions from Dispatcher
*/
FluxStoresPool.off('MyStoreID');
/*
switch store on
restore normal mode - the store will receive actions
*/
FluxStoresPool.on('MyStoreID');
/*
get store
You need it for your React Container's calculateState method
*/
FluxStoresPool.item("MyStoreID");
/*
get array of stores
You need it for your React Container's getStores method
*/
FluxStoresPool.arr("MyStoreID","MyStoreID2","MyStoreID3");
Different stores for the same component instances
Let's suppose you have two instances of the same component:
<MyComponent id="1"/>
<MyComponent id="2"/>
And you need a separate store for each of them. Is it possible? That's simple!
MyComponent.jsx
import FluxStoresPool from 'flux-stores-pool';
...
class MyComponent extends React.Component {
constructor(props) {
super(props);
/*
use props id to generate store's name, also you can pass the id to the store
*/
FluxStoresPool.create("MyStoreID"+props.id, MyStoreClass, props.id);
}
static getStores(props) {
return FluxStoresPool.arr("MyStoreID"+props.id);
}
static calculateState(prevState,props) {
return {
MyStore: FluxStoresPool.item("MyStoreID"+props.id).getState(),
}
}
componentWillUnmount(){
/*
you can drop your store here, if you wish
*/
StoresPool.remove("MyStoreID"+this.props.id);
}
...
/*
this is SUPER IMPORTANT - to add withProps=true to your Container creation.
This forces Flux to pass properties to getStores and calculateState
*/
export default Container.create(MyComponent, {withProps: true});
MyStoreClass.jsx
import {ReduceStore} from "flux/utils";
...
class MyStoreClass extends ReduceStore {
constructor(customID) {
super(AppDispatcher);
this.customID=customID;
}
getInitialState() {
/*
please note - you can't use customID here, it's still undefined
*/
return Immutable.Map({
"something":""
});
}
reduce(state, action) {
/*
but here it's set! and you can use it to filter actions
*/
if(action.customID!=this.customID) return state;
switch(action.type) {
case SOME_ACTION :
//do something
...
/*
And do not forget to export store class, not an instance
*/
export default MyStoreClass;
You have a separate store for each MyComponent instance. Congratulations!
How does it work?
We keep classical Flux scheme untouchable, just put stores into FluxStoresPool collection. It doesn't require any changes in Dispatcher, Stores or API codes, but allows to create, remove, register and unregister stores "on the fly". We can even create stores for each instance of a Flux container.
Is it a "canonical Flux way"? Suppose so. We don't spoil Flux data flow, we just add a tiny good-looking control panel with switchers to a pool with our stores.
Examples
./examples/basic - Basic scheme.
There is a very simple component/container App that uses FluxStoresPool to create AppStore (not an Apple's one :) ). Then it creates a button
<button onClick={AppActions.onButtonPressed} >Counter: {counter} / Press me!</button>
When you press the button - AppStore increases counter and forces App to re-render itself.
./examples/instances - Separate stores for instances of the same React component.
There are TWO instances of the App and we create an AppStore instance for each of them.
./examples/advanced - The final is here.
There you can create/remove components with their own stores, can connect, disconnect, create and remove their stores on the fly.
That's all, folks!