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?
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.
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.
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.
https://github.com/mobxjs/mobx/ is now monorepo with all the packages, so nothing is deprecated.
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.
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 :
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
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.
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"
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With