How do you handle multiple instances of a React component and MobX store, when using MobX with React hooks?

D

Drew

Guest
I am looking into using MobX with React hooks, and am having trouble handling multiple instances of a React component and MobX store. It seems in my MobX store file, I can create and export a context of the store using React's createContext, and use that context in the React component. This is a problem, because the context would be shared among all instances of the component. I am also hesitant about creating the instance of the MobX store from within the React component, since I want to be able to get the state from outside that component.

I have created a simple counting app example, where there are three counter components inside an app component, which will also display the total from the counters. How would I write this using hooks, rather than the older Provider, or are hooks just not the right tool for this type of use case?

//components/counterApp.jsx
import React from 'react';
import Counter from './counter.jsx'
import { Provider, inject, observer } from 'mobx-react';

const CounterApp = inject('store')(observer(({ store }) => {
return (
<React.Fragment>
{store.counters.map( (counter, idx) => {
return (
<Provider key={idx} store={counter}>
<Counter/>
</Provider>
);
})}
<div>
Total: {store.total}
</div>
</React.Fragment>
)
}))

export default CounterApp;


//components/counter.jsx
import React from 'react';
import { inject, observer } from 'mobx-react';

const Counter = inject('store')(observer(({ store }) => {
return (
<div style={{display:'inline-block'}}>
<div>
{store.count}
</div>
<button onClick={() => store.count++}>+1</button>
</div>
)
}))

export default Counter;


//stores/CounterAppStore.js
import { observable, computed } from 'mobx';
import CounterStore from './CounterStore.js'

class CounterAppStore {
@observable
counters;

constructor() {
this.counters = [];

for (let i = 0; i < 3; i++) {
this.counters.push(new CounterStore());
}
}

@computed get total() {
return this.counters.reduce((total, counter) => total + counter.count, 0)
}
}

export default CounterAppStore;


//stores/CounterStore.js
import { observable } from 'mobx';

class CounterStore {
@observable
count;

constructor() {
this.count = 0;
}
}

export default CounterStore

Continue reading...
 
Top