I have three related questions about best practices with “computed”.
TL;DR: What do I need to think of myself and what does reconciliation do out of the box.
Let’s say I load a hefty dataset into a data variable:
data = asyncComputed( await fetch … return data )
I then have convenience computed prop that formats this data:
@computed get timeseries() {
const data = this.data.get()
const timeseries = nest()
.key(d => d.geo)
.entries(data)
return timeseries
}
And a third convenient prop that is calculated on top of the timeseries:
@computed get extentX() {
const timeseries = this.timeseries.get()
const extentX = extent(timeseries, d => d.time)
return extentX
}
Is there a risk that a render happens before all these computations are done or does MobX ensure that this is reconciled before?
Is there a better way of structuring this code to avoid chaining of computed props?
Let’s say the first async is triggered when a property (id) is changed on an object and that this object is later updated from the same chain of events:
variable = { id : “my-variable”, extent: undefined}
data = asyncComputed( await fetch api?id=variable.id )
=> computes extent => results in variable.extent = [200, 400] Is there a risk that this can set off an infinite loop or is it safe to update an object property like this?
here are my thoughts on this topic.
@observerit just wraps a render function inautorun(Proof)From #1 we can make a conclusion that if we have a chain of computed they are evaluated synchronously like:
observable -> computed 1 -> computed 2From #2 we can say that in order to run a side effect - this computed chain will have to end with autorun
observable -> computed 1 -> computed 2 -> autorunThis already leads us to point #3. That
@observeris a HOC that wraps you Component and controls whenever it needs to be rerendered. This is not now under control of your component.So answering your questions:
computedwill callautoruncomputedis powerful approach and should not be avoided, just used wizdomly.From docs: