Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access stores from class using mobX and react Context

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?

like image 418
Englund0110 Avatar asked Jan 19 '19 01:01

Englund0110


People also ask

Does MobX use context?

It is not mandatory to use react context with Mobx but it is recommended now officially on the mobx-react website. So, It is better to use Mobx with react context starting from mobx-react 6.

Does MobX work with functional components?

In this tutorial, we will learn how to use MobX with React Functional Components. MobX being a very useful state management library reduces the code that needs to be written for global state management. Mobx is easy to use and quick to learn.

How do I use react JS in MobX?

We can use cd mobx-react to go into the folder. Now, inside of the src folder, we can create a folder for our components, create a PetList component inside the folder, and open the file in your favorite editor.

Is MobX deprecated?

https://github.com/mobxjs/mobx/ is now monorepo with all the packages, so nothing is deprecated.

How to use mobx with react?

Assumed you have a React app ready, we can install the necessary dependencies to work with MobX. We will create 2 stores, user and note store, user store will only have a user name as observable and a set function to modify the name. Note store will be keeping an array of notes.

How to use mobx store in any class component?

withStore is a custom HOC (Higer order component) to use mobx store in any class component. Go to your main file. App.js in case of create-react-app and paste this :

What is the difference between mobx and mobx-react?

Mobx is the main library and mobx-react has the mobx binding for react. Install both Mobx and Mobx-react using the following command : If you had already setup react app and Mobx then Make sure that mobx-react is 6.x or higher

Why use context instead of provider in mobx-react?

Note that your Provider / inject way is not the recommended way by mobx-react anymore, they suggest to use Context like I did. But, why? The thing is that it is a similar concept like making private variable inside any object-oriented programing language so that other classes cannot access and change it directly.


1 Answers

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"
    }
}
like image 115
Ehsan Avatar answered Sep 26 '22 00:09

Ehsan