Why not create new observables in computeds? #3136
-
I'm trying to understand the reason behind the second rule of computeds: Why is it a bad idea to create an observable from a For example, if there is a need to make an HTTP request whenever a specific selection changes, is this really wrong to do? import { computed, makeObservable, observable } from 'mobx';
import type { IPromiseBasedObservable } from 'mobx-utils';
import { fromPromise } from 'mobx-utils';
class Store {
@observable selectedItemId: string = 'item1';
constructor() {
makeObservable(this);
}
@computed
get name(): IPromiseBasedObservable<string> {
return fromPromise(fetchItemName(this.selectedItemId));
}
}
async function fetchItemName(id: string): Promise<string> {
return 'bob'; // or actually fetch the name asynchronously from somewhere
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
A computed is a pure function that depends on observables. It shouldn't have side effects to remain pure. I'd complete the task in this way: class Store {
@observable selectedItemId: string = 'item1';
@observable name?: IPromiseBasedObservable<string>;
constructor() {
makeObservable(this);
}
@action selectItem(itemId: string) {
this.selectedItemId = itemId;
this.name = fromPromise(fetchItemName(this.selectedItemId))
}
} |
Beta Was this translation helpful? Give feedback.
-
Computed (arguably) represents data that can be derived/reconstructed from your state at any point in time - the cache is just an optimization, not something to design your system around. @computed({ keepAlive: true })
get derivedStore() {
return new DerivedStore({ dependency: this.dependency })
} Does it make sense to loose whole state and subscriptions associated with Technically nothing's gonna break, doesn't matter whether the returned thing is observbale or not. It's just a matter of whether it makes sense or not. Lots of people actually does this. |
Beta Was this translation helpful? Give feedback.
Computed (arguably) represents data that can be derived/reconstructed from your state at any point in time - the cache is just an optimization, not something to design your system around.
You should assume that accessing
name
3 times will result in a creation of 3 promises. With this reasoning it doesn't make sense to return anything statefull and therefore observable.This is because the cache dependents on usage - you assume that your class is used in a particular way, but from the consumer point of view, it's just a field/value as any another.
Eg, in react's concurrent mode, the field can be read during render multiple times, but the component may not ever get committed, so the fetch r…