8

I am strugling a bit with mobx/mobx-react-lite and react hooks.

From a class i want to update a property in one of my stores, but somehow i cant get it to work. Here are some examples of how my stores are combined, and the component and class i want to call my store from. I am using Context from react to get the stores in my hook component, and that works perfectly.

// FooStore

import { observable, action } from "mobx";
import ExampleClass from "app/services/exampleClass";

export class FooStore {
    @observable
    public foo: string = "";

    @action
    public doSomething() {
        this.foo = ExampleClass.doSomething()
    }
}

export default FooStore;

// BarStore

import { observable, action } from "mobx";

export class BarStore {
    @observable
    public bar: number = 0;

    @action
    public setBar(value: number) {
        this.bar
    }
}

export default BarStore;

//Store (Combining the stores to one, and exporting with createContext())

import { FooStore } from "./FooStore";
import { BarStore } from "./BarStore";
import { createContext } from "react";

class Store {
    public fooStore: FooStore;
    public barStore: BarStore;
    constructor(){
        this.fooStore = new FooStore();
        this.barStore = new BarStore();
    }
}

const stores = new Store()

export default createContext(stores);

This is the class i want to be able to call my barStore. (Notice, not a component class)

//ExampleClass

export default class ExampleClass {
    public static doSomething(): string {
        // ...

        // Call BarStore.setBar(1000)

        return "Some string"
    }
}

Can anyone push me in the right direction for this?

Englund0110
  • 514
  • 2
  • 5
  • 23

1 Answers1

4

Context is a React concept. it's not good to export your store by Context. (May be you should need to use it in another environment !) You should export store itself and wrap it through context in your highest level component.

//Your store:

import { FooStore } from "./FooStore";
import { BarStore } from "./BarStore";

class Store {
    public fooStore: FooStore;
    public barStore: BarStore;
    constructor(){
        this.fooStore = new FooStore();
        this.barStore = new BarStore();
    }
}

const stores = new Store()

export default stores;

//App.js ...

import store from './yourStore';
import { createContext } from "react";

const GlobalStore = createContext(store);

export default () => {
    <GlobalStore.Provider>
       <Main />
    </GlobalStore.Provider>
}

//Any other js file

import store from './yourStore';

export default class ExampleClass {
    public static doSomething(): string {
        // ...

        store.BarStore.setBar(1000)

        return "Some string"
    }
}
Ehsan
  • 1,093
  • 1
  • 12
  • 21
  • Hey Ehssan! Thanks for your help. I have added to my app.ts, but it requieres a value, so i ended up with . But how can i get the store from context by using the useContext in my components? Or do you recommend importing it like const store = store (from ./yourStore) – Englund0110 Jan 21 '19 at 20:42
  • @Englund0110; You can create a module and call React.createContext inside it. then export the output value. Use this module anywhere you want and pass it down thorough useContext. – Ehsan Jan 22 '19 at 06:10
  • 2
    Isn't the Store in this case a singleton which therefore doesn't actually use Context at all in the ExampleClass? I believe the right way would be to set `ExampleClass.contextType = GlobalContext` and then use in class as `this.context.fooStore` but I'm just trying to wrap my head around this whole Context thing. – kachnitel Jan 09 '21 at 03:50