Let's stay I have this myObject loaded via an API call:
myObject = {
fieldA: { details: 'OK', message: 'HELLO' },
fieldB: { details: 'NOT_OK', message: 'ERROR' },
}
Only details and message of each field can change. I want this object to be observable in a MobX store (which properties? to be defined below). I have a simple React component which reads the two fields from the store:
@observer
class App extends Component {
store = new Store();
componentWillMount() {
this.store.load();
}
render() {
return (
<div>
{this.store.fieldA && <p>{this.store.fieldA.details}</p>}
{this.store.fieldB && <p>{this.store.fieldB.details}</p>}
</div>
);
}
}
I read this page trying to understand what MobX reacts to, but still didn't get a clear idea. Specifically, which of the 4 stores below would work, and why?
1/
class Store1 = {
@observable myObject = {};
@action setMyObject = object => {
this.myObject = object;
}
load = () => someAsyncStuff().then(this.setMyObject);
}
2/
class Store2 = {
@observable myObject = {};
@action setMyObject = object => {
this.myObject.fieldA = object.fieldA;
this.myObject.fieldB = object.fieldB;
}
load = () => someAsyncStuff().then(this.setMyObject);
}
3/
class Store3 = {
@observable myObject = { fieldA: {}, fieldB: {} };
@action setMyObject = object => {
this.myObject = object;
}
load = () => someAsyncStuff().then(this.setMyObject);
}
4/
class Store4 = {
@observable myObject = { fieldA: {}, fieldB: {} };
@action setMyObject = object => {
this.myObject.fieldA = object.fieldA;
this.myObject.fieldB = object.fieldB;
}
load = () => someAsyncStuff().then(this.setMyObject);
}
All of the above will work, except for solution 2. That because as described in Mobx docs about objects:
When passing objects through observable, only the properties that exist at the time of making the object observable will be observable. Properties that are added to the object at a later time won't become observable, unless
extendObservable
is used.
In the first solution you re-assign the object again with the properties already exist in the returned object. In 3 and 4 you initialized the object with those 2 properties so it works.
Also I think in your component example you meant to use it like this (otherwise, it won't work in any way):
render() {
const { myObject } = this.store;
return (
<div>
{myObject && myObject.fieldA && <p>{myObject.fieldA.details}</p>}
{myObject && myObject.fieldB && <p>{myObject.fieldB.details}</p>}
</div>
);
}
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