Lifecycles
See original GitHub issueI was looking at the project I need to modify to use mobx-jsx
and of around 300 classes the only thing I can see could complicate me is the lifecycle componentWillUnmount which seems to me I cant avoid it. I will give you examples:
A component that sets a MutationObserver to redraw a canvas when something is resized to then turn off the observer on componentWillUnmount
A component that use sockets, like in socket.on(......)
and on componentWillUnmount socket.off(...)
There’s seem to be a concept of cleanup via mobx, but I dont see how that will work per component, on the counter++ example I added two counters and removed one later on, the setTimeout kept running on the unmounted component. Also with mobx you can create a global state that isn’t attached to any component which is very handy. On Solid you do something similar to cleanup but I guess is tuned to the component? Maybe is per file? I would prefer a componentWillUnmount lifecycle as in some situations I have many components on the same file and the intention will look more clear. Thanks in advance!
For completeness, I read on https://github.com/ryansolid/mobx-jsx/issues/11 that componentDidMount could be simulated by using Promise.resolve().then(() => /*... */);
on the constructor or render function(maybe better on the render function).
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (9 by maintainers)
Yeah this is one I find I’m always explaining because it is non-obvious until it is.
cleanup
should be what you are looking for. In Solid I call itonCleanup
but it’s the same thing. Essentially I leverage the reactive context to do all disposal.If you picture your app basically a bunch of nested
autorun
s that track all the disposal methods of their childautorun
instances, that upon being re-evaluated or cleaned up themselves they clean up their children you are basically there. If anautorun
creates childautorun
s any re-execution of the parent is going to create a new one, so the old one needs to be released. We are basically handling this the same way a MobXautorun
clears all dependencies before each run to track them all over again.Now if you are wondering about Components, it’s the realization that if there is nothing conditional in selecting their rendering then they will live the whole life of the app. So they are tied to the topmost autorun. However, if there are conditions, then that will be it’s own nested
autorun
scope that will only re-evaluate when the condition changes and handle it’s own nested disposal. So basically you can register acleanup
method anywhere and it will run when the time comes based on the nested reactive tree. Components don’t need explicit will unmount methods since registeringcleanup
will run when the parent cleanups or re-runs itself (perhaps changing a tab in the UI).In so the best pattern for global state is Context like React since the Provider puts creation under the reactive tree… MobX-JSX has context unlike React has no tie to the render mechanism in itself so there is no performance hit etc… See it here: https://codesandbox.io/s/mobx-counter-context-wlu1x
So the mentality here is Components are ephemeral. They serve as factory functions that maintain state by the closures created in MobX’s reactive computations. So lifecycles don’t make sense. In the purest sense all bindings are side effects of these computations. Those side effects consist also of nested computations which are all managed as part of each computations own lifecycle. There are no lifecycles outside of that. But since it isn’t tied to a components the reactive primitives are fluid between global and local state. It’s just the same pattern all the way down.
Does that help?
That’s great. And I think that’s sufficient then.
I love reactive primitives because I can model almost anything but some problems are difficult even for me so it’s nice sometimes to give a syntax to make it just automatically handle it for you. But I’m also very particular about my approach with Solid otherwise I might just be using MobX in my core so I understand why it doesn’t align. I’ve put more time into Solid specifically to worry about more complicated things like lifecycle (which a reactive library doesn’t really have) and trying to tell a consistent story but it does complicate everything (in theory to allow certain things to be easier).
I’m definitely not primarily focused on the localized problem (like looking at the component file in front of me) when working through my decisions. You can tell a library like Svelte is but it has limits elsewgere. MobX JSX keeps things simple enough with enough room to branch out that I’m glad it exists. At one point this was really all my ambition for Solid really. It’s just growing beyond that.