I have an observable object, where I want to store some data. Keys are unique IDs for my customer entity, and values are arrays of customers' orders (which are objects themselves).
I initialize an object with:
@observable data = {};
Then, when I get data from network, I want to store them, using:
@action
saveData(customerId, ordersForCustomer) {
this.data = extendObservable(this.data, {
[customerId]: observable(ordersForCustomer);
}
}
Unfortunately, it seems my object (or its properties) are not being watched.
Why is this? And how can I fix this? Is there something special I need to know about how observable objects work with arrays as its values?
It can be used to trap existing object properties and make them observable. Any JavaScript object (including class instances) can be passed into target . Typically makeObservable is used in the constructor of a class, and its first argument is this .
toJS. Usage: toJS(value) Recursively converts an observable object to a JavaScript object. Supports observable arrays, objects, Maps and primitives. It does NOT recurse into non-observables, these are left as they are, even if they contain observables.
ObservableArray is an array that allows listeners to track changes when they occur.
This problem is brought up in the Common pitfalls & best practices section of the documentation:
MobX observable objects do not detect or react to property assignments that weren't declared observable before. So MobX observable objects act as records with predefined keys. You can use
extendObservable(target, props)
to introduce new observable properties to an object. However object iterators likefor .. in
orObject.keys()
won't react to this automatically. If you need a dynamically keyed object, for example to store users by id, create observable _map_s using observable.map.
So instead of using extendObservable
on an observable object, you could just add a new key to a map:
@observer
class App extends Component {
@observable data = asMap({});
constructor() {
super();
setInterval(() => {
this.data.set(Math.random().toString(36).slice(-5), Math.random());
}, 1000);
}
render() {
return (
<div>
{ this.data.entries().map(e => <div> {e[1]} </div>) }
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
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