-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't autoconvert function without arguments into getters #421
Comments
You can't expect that any arbitrary object coming from UI can be automatically turned into observable. let kitten = { _name: "" };
kitten.name = asGetter(() => kitten._name.trim()); // ui still need to know about mobx internals
kittensStore.addKitten(kitten); Btw, I think that However, I see your point about consistency, I just don't think it's a good example. Forbid using functional properties with length > 0 inside objects passed to observable/extendObservable So, if there is a function in observable/extendObservable call, it's either a getter or it must be wrapped into |
Yes, but thats not really desired behaviour, it happen only because we have no way to make it return true in current JavaScript.
Yes, I'm observing reference to
There is no any necessity to define mobx computations: let kitten = { _name: "" };
kitten.getTrimmedName = () => kitten._name.trim();
// or:
Object.defineProperty(kitten, 'name', { get: () => kitten._name.trim() }); If I really want to do this optimization, I can do it explicitly in the store: class KittensStore {
@observable myKittens = [];
addKitten({ getTrimmedName }) {
this.myKittens.push({ name: computed(getTrimmedName) });
}
}
Agree SummaryMy point is that if user turns object of shape |
Let me rephrase it:
When I started with MobX, I did something like this: const control = observable({
value: "intialValue",
validate: () => console.log("validating...")
}); What was my expectation? Not that the property My point is: To me personally, it doesn't really matter if I have to write computed() or asReference(). Neither of those defaults will work for any plain object, but I think that I would have to write computed() far often then asReference(). Still, I don't like making a difference based on the number of arguments, there is enought magic involving property type (I don't like this magic either, but I kind of see and appreciate it's practicality). |
I think it's quite natural to expect object to stay the same shape after adding to ObservableArray by default. If the key is a function, it can be observed by reference, as well as RegExp or Date.
Sane defaults should correspond to what user expects if we're making user-friendly library.
Explicit code is often more verbose. I'm using es2015 classes for representing app state, so I have to use |
It would be very interesting to hear @mweststrate thoughts on this. |
I agree only partially. Everybody can expect something else. An expectation can turn into something absolutely impractical in the end. I think that the difference between our views is, that you see observable()/extendObservable() as something which can turn any domain object, with all it's complexity, into basically the same object, but somehow sanely observable. If explicit code doesn't bring you any discomfort, why don't you turn your kitten and it's properties into observable explicitely, like you have to do with your classes? Both are quite smart objects, they are not just dumb state holders, so is it because it's not possible to do this
It's undesired for your plain objects, which you want to turn into observables. But as I stated earlier, It really doesn't matter to me, what will be the default behavior, as far as it will be consistent. With that in mind, if there are scenarios, where it would be beneficial, than it's worth considering. |
Renaming |
This magic behavior of computed functions bothers me for a very long time already. But personally didn't find a more satisfying approach. Just some thoughts
So bunch of thoughts, no conclusion yet :) Could slowly move towards encouraging |
@mweststrate I do like the automatic computed in |
It's not possible to use them as such, because they become a getter (computed prop).
In that case, I think there is no point in prohibiting multi args functions. When If |
@urugator sorry you're right. On the last question, what do you mean by @andykog Thought about it, I think the current behavior should indeed be deprecated, as in unexpectly 'breaks' the type of an assignment, especially in less obvious cases like: const x = observable({ y: null })
x.y = { z: function() { console.log("hi") }
x.y.z() // nope |
@mweststrate Actual prop descriptor, obtained by extendObservable(this, {
side: 1,
get volume() { return this.side * this.side; }, // turns into computed prop
viewClass: function() {....} // plain functions are simply observed by reference, arg count doesn't matter
}) |
@urugator, detecting and turning getters into computed value is awesome idea, by the way! And it resolves another issue of turning getter into static observable value. |
I think the For that reason I think I'll prefer the approach as suggested in #42, although it is a bit more verbose:
|
If I want a normal getter I shouldn't define it as an observable in the first place. |
@urugator, normal getter will still be tracked, creating it with
@mweststrate, Can you imagine some use case when this can lead to a problem? Observable getters behave the same way as normal and performance overhead for simple getters is miserable, right? I'm not opposing, just asking. |
No cannot think of such a use case, and I think it is quite easy to implement. But somehow it feels a bit arbitrary that |
As @andykog made clear, there is no point in observing a getter field, because it's "value" can't be changed in an observable way. So a getter defined in an observable is practically unobservable (or am I missing something?), which seems a bit wierd to me. Also, I think, it kinda makes sense to turn getter into computed, because getter is in fact a normal field, which value is a just a derivation of other field/s. Similary to: And the least importantly, it's more appealing :)
EDIT:
In that case I think the following should feel arbitrary as well: EDIT: fixed getter syntax |
Note that the above syntax won't work afaik, should be But yes, I admit it looks tempting. Was quite easy to setup, see above commit :) |
Btw I actually never realized this is valid ES5 syntax :-/ |
You have a typo in test description "... plan object ...". |
it is wrapped in an action indeed. thanks for the idea btw, despite my Op wo 31 aug. 2016 22:52 schreef urugator [email protected]:
|
Released as 5.2.1, opened a separate feature to kill the current behavior. |
For me, one of the least pleasant parts of mobx is automatic converting function without arguments to getters.
The problem
Proposition
It would be really nice not to make such a bold assumption. We can introduce special modifier
computed
, so if one really want to create getter, he can show it explicitly:Pros:
Cons:
PS: I know about
asFlat
UPD
changed
asGetter
->computed
The text was updated successfully, but these errors were encountered: