Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Instances of the same Store #505

Closed
harsimranb opened this issue Jan 17, 2017 · 6 comments
Closed

Multiple Instances of the same Store #505

harsimranb opened this issue Jan 17, 2017 · 6 comments

Comments

@harsimranb
Copy link

I looked through the documentation and could not figure out a way to do this. Essentially, I am building a modular plugin system, in which I am hoping to have one Reflux store per PluginComponent. However, it's possible that there can be multiple PluginComponents on the page that share the same store, as shown below.

class PluginStore extends Reflux.Store {
     constructor(pluginId) {
     }
}

In the component:

class PluginFrame extends Reflux.Component {
     constructor() {
          ...
         this.store = new PluginStore(pluginId);
     }
}

Is this possible with this library at the moment? I've looked at a few others and haven't found one that achieves this.

@BryanGrezeszak
Copy link
Contributor

BryanGrezeszak commented Jan 17, 2017

Yes. Multiple ways actually.

For one, it's actually perfectly possible to instantiate Reflux store classes and assign the instance to this.store in the component.

However, that limits you in a few ways. Mainly that global state (which relies on tracking each singleton of a store) will not work.

So instead, I would recommend creating a factory for the store class. Here's a fully functioning example:

var MyActions = Reflux.createActions(['increment']);

// THIS is the important part! The function returns a completely new class on each call.
function myStoreFactory(id, start)
{
    class MyStore extends Reflux.Store
    {
        constructor() {
            super();
            this.listenables = MyActions;
            this.state = {count:start};
        }
        
        onIncrement() {
            this.setState({count:this.state.count+1});
        }
    }
    
    MyStore.id = id;
    
    return MyStore;
}

class MyComponent1 extends Reflux.Component
{
    constructor(props) {
        super(props);
        this.store = myStoreFactory('store1', 10);
    }
    
    render() {
        return <div>count: {this.state.count}</div>;
    }
}

class MyComponent2 extends Reflux.Component
{
    constructor(props) {
        super(props);
        this.store = myStoreFactory('store2', 20);
    }
    
    render() {
        return <div>count: {this.state.count}</div>
    }
}

class Root extends React.Component
{
    constructor(props) {
        super(props);
    }
    
    render() {
        return (
            <div>
                <MyComponent1 />
                <MyComponent2 />
            </div>
        )
    }
}

This preserves basically every normal functionality, since you're actually making a new class every time myStoreFactory is called. So if you check the global state, it's all tracking just fine.

@harsimranb
Copy link
Author

@BryanGrezeszak Thanks for the quick response. That is awesome, totally forgot about using a factory. My only other question is can I cache the Stores for the same ID, since I want to reuse those . Something like:

var myStores = [];
function myStoreFactory(id, start)
{
    if(myStores[id]) { 
        return myStores[id];
    }
    class MyStore extends Reflux.Store
    {
        constructor() {
            super();
            this.listenables = MyActions;
            this.state = {count:start};
        }
        
        onIncrement() {
            this.setState({count:this.state.count+1});
        }
    }
    
    MyStore.id = id;
    myStores[id] = myStores;
    return MyStore;
}

@BryanGrezeszak
Copy link
Contributor

Yeah. That would usually be an object, not an array, but the general gist is right.

Or: any store with an id gets stored at Reflux.stores anyway. So you could just check that.

@harsimranb
Copy link
Author

@BryanGrezeszak Thanks, that's working awesome. Only thing is the Action is getting fired for both instances of the store. I am using the id which is getting stored in Reflux.stores.

@BryanGrezeszak
Copy link
Contributor

BryanGrezeszak commented Jan 18, 2017

I'm confused by what you mean. In flux you don't call actions for a store. If your store is listening for an an action and it is called, then it'll catch it. So yeah, it would be called for any store that is listening.

@harsimranb
Copy link
Author

harsimranb commented Jan 18, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants