-
Notifications
You must be signed in to change notification settings - Fork 641
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
introduce lazy loading of types [WIP] #247
Conversation
Hey @mattiamanzati I like the idea, not entirely sure about the entire api yet: First of all, I would skip the Secondly, which I am not sure about, is that it might be more convenient to have a method that performs the loading, rather then a reaction. Although it makes it arguably a bit more imperative. What about something along these lines:
and then make the type of where const UnloadedType = types.model({
isPending: literal(true), // always true, but for convenience, see example below
state: enum("unloaded", "loading", "error") // no loaded state, because this node gets replaced!
}, {
load() {
// kicks of the promise if not already done so
// once promise is resolved, instance is replaced like in the PR
}
} Example from test const Model = types.model(
"Model",
{
lazy: types.lazy(
() => Promise.resolve(SomethingUseful)
)
},
{
setLoaded() {
if (this.lazy.isPending)
this.lazy.load()
// else, already loading
}
}
) I think this api is smaller, and feels more composed, as it is just a union (although same limitiations apply; only as direct descendant of a structure). I doubt about the |
Yeah, loading the type through a method could be a smarter idea, even if loading should be triggered after some method being called. The user could use the reaction-like syntax by setting up a reaction in the afterAttach of the parent. |
Good points. I need to think harder :-P. |
Ok, I think the replacement type should be frozen indeed, and not overrideable :) Didn't verify it against the actual implementation, but I think api signature should be like:
This means that If you put I am not sure if Typescript might become quite annoying as strict null checks will probably trigger on accessing any attribute in a lazy type, as it doesn't know whether it is loaded already or not. |
Uhm, that's also a fair point.
This allows the TypeChecker to easily dispatch between the loaded or unloaded case, by simply asserting the status string. This also enforces the developer to check for that, so warnings by TypeScript will be LGTM. It will also respect in time travel errors on render due to the state of type loading (e.g. accessing a computed property if the type has not loaded yet). On the other hand, the user can't simply drop it in as replacement type. |
Yeah that might be simpler to work with and have less potential issues. On the other hand api / usage wise it is indeed quite ugly as it is untransparent to the consumer side of things. Also it might be quite how to operate with lazy types in general. If you have e.g. I also don't have any clear idea about lazy loading value objects yet. I think it might be best to put this PR on hold, until we figured a really nice pattern or an urgent real life need? I think this needs some more time to be thought trough :) |
|
For 3: having maybe a HigherOrderType that loads data somehow automatically
when needed, like fromResource and lazyObsevable in MobxUtils
Op do 20 jul. 2017 om 21:55 schreef Mattia Manzati <notifications@github.com
…:
1.
Yeah, I'd prefer that too, would avoid lots of issues :)
2.
And that's why I originally wrote a reaction predicate as load
trigger, it's on the declared type, so the user understand that refers to
the type, and avoid putting messy additional things over the instance :)
3.
Uhm, what do you mean by value objects?
4.
Sure, was initially opened for that, only to explore it API wise and
implementation wise :)
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#247 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABvGhAk6vbHcLw8-zrOMbvA1xkBZLzDXks5sP7DMgaJpZM4OVnjy>
.
|
This seem like a very cool feature, do we have any new updates on this feature? |
I think we can now use custom references to achieve the same right? Or would a separate type be nicer? Kinda out of the discussion :). Sry! |
Any updates on this? I'm interested in switching over from Redux, but we need to be able to match functionality of lazy loading our reducers. |
I think for now we can close this issue? I don't think the demand is that high atm, and alternatively one can keep multiple tree definitions separated and store them in volatiles of a root component. |
I hope you'll reconsider. Lack of code splitting akin to Redux's |
Reading the above solutions with references and volatile - I didn't quite understood it.
Here I want FormStore instantiated only after login.
What should I do ? |
I think in my case I should do:
|
Is there any way to accomplish dynamic types with observable properties at the moment? |
@mweststrate By using multiple trees stored as volatiles in a root component, wouldn't that prevent them from having references from one tree to another? (I tried it, and can confirm this doesn't seem to work) I'd be keen to contribute to help make this feature happen as I think dynamic loading is pretty important in a healthy codebase nowadays. What would convince you that it's worth adding to MST? |
This PR introduces lazy loading.
This is done by introducing in MST a new type composer named "lazy".
This type composer has the following parameters:
This types can be used only as child of ComplexTypes (model, array, map) as it will trigger behind the scene a replace of the value of the corresponding property. For this reason, performing actions like onPatch(this.lazy, fn) on afterAttach may break because the node will be destroyed and replaced later.
cc @arackaf