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

Root store pattern #4

Open
Quernest opened this issue Aug 11, 2019 · 4 comments
Open

Root store pattern #4

Quernest opened this issue Aug 11, 2019 · 4 comments

Comments

@Quernest
Copy link

Hi!

Thank you for this implementation, but I don’t understand a bit. Could you provide an example how to use one store inside another (aka. RootStore pattern) using "initial data"?

It's correct use something like this?

let store;

class RootStore {
  constructor(initialData = {}) {
    this.authStore = new PostStore(this, initialData.postStoreInitialData);
    this.uiStore = new UIStore(this);
  }
}

export function getStores(initialData = { postStoreInitialData: {} }) {
  if (isServer) {
    return new RootStore(initialData);
  }

  if (!store) {
    store = new RootStore(initialData);
  }

  return store;
}

Then

class PostStore {
  constructor(rootStore, initialData = {}) {
    this.rootStore = rootStore;
    this.post = initialData.post;
    this.postId = initialData.postId;
  }

  // just for example
  doSomething() {
    this.rootStore.uiStore.setSearchOverlayOpen(true);
  }
}
@borekb borekb mentioned this issue Aug 12, 2019
4 tasks
@borekb borekb changed the title Example Root store pattern Aug 12, 2019
@borekb
Copy link
Owner

borekb commented Aug 12, 2019

Hi, thanks for the question, I plan to add the root store pattern sometime this week.

@msreekm
Copy link

msreekm commented Oct 21, 2019

looking forward for rootstore pattern as well. I think the above code should work, but iam interested in seeing what @borekb 's implementation would be. Thanks for the repo btw.

@nigel-dewar
Copy link

First of all, thank you for your repo, its helping me where lots of others cannot.

Did you end up getting time to implement the rootStore? I am looking at your repo and it doesnt look like you did it?

@borekb
Copy link
Owner

borekb commented Apr 30, 2020

Sorry folks, this has not been high on my priority list 😄. Here's a copy/paste from our stores/RootStore.ts, hope this helps as a quick source of inspiration.

/**
 * Implements the RootStore pattern and a universal way to work with all the stores at once.
 * For example, `_app.tsx` does not iterate over stores to get their data, it calls `rootStore.toJSON()`.
 */
export class RootStore implements MobxStore {
  brandStore: BrandStore;
  cartStore: CartStore;
  categoryStore: CategoryStore;

  constructor(initialData: RootStoreInitialData | null, apolloClient: ApolloClient<{}>) {
    this.brandStore = getStore(BrandStore, initialData ? initialData.brandStoreInitialData : null, apolloClient, this);
    this.cartStore = getStore(CartStore, initialData ? initialData.cartStoreInitialData : null, apolloClient, this);
    this.categoryStore = getStore(
      CategoryStore,
      initialData ? initialData.categoryStoreInitialData : null,
      apolloClient,
      this
    );
  }

  async fetchInitialDataDuringSSR(ctx: NextPageContext): Promise<void> {
    await Promise.all(
      this.stores.map((store: MobxStore) => {
        if (store.fetchInitialDataDuringSSR) {
          return store.fetchInitialDataDuringSSR(ctx);
        } else {
          return Promise.resolve();
        }
      })
    );
  }

  toJSON(): RootStoreInitialData {
    return {
      brandStoreInitialData: this.brandStore.toJSON(),
      cartStoreInitialData: this.cartStore.toJSON(),
      categoryStoreInitialData: this.categoryStore.toJSON(),
    };
  }

  private get stores() {
    return [this.cartStore, this.categoryStore];
  }
}

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

4 participants