Dispose function not actually disposing of anything
I'm running Solid as a partial view inside another, non-Solid app. I've used webpack to export Solid's render function and assign it to the Window object (so i can access it from the outer app by calling window.render) and then I dynamically import the components I need and render them to a div on the page, and I hold on to the return value of the render function so I can dispose of it later. When I want to swap one component out for another, I call that dispose function, dynamically import the new component, and render that instead. The problem is that this doesn't work. When I call the dispose function, it clears out the div on the page, but it doesn't trigger any cleanup functions, so all effects keep tracking and any content rendered outside that div with portals persist.
If, instead, I export render within each component, and then import it along with the component and use that render function to render, then it does dispose properly. However, I'd like to not have to add export { render } from "solid-js/web" at the end of every file if I can avoid it.
Is there a solution for this issue that lets me render a dynamically imported component and dispose of it when I need to without having to export render in every component?
5 Replies
In general, cleanups do get called when dispose is called (example: https://playground.solidjs.com/anonymous/b2b30499-f7ac-4dab-a4f8-80cd0ea85cd8), so it is likely that the reason this isn't happening in your case is do to something set up incorrectly
The most likely cause is that onCleanup is being called without an "owner", which is sometimes the result of the component not being passed lazily to render (so the component tree renders before the base owner gets set up)
When there is no owner, all reactivity breaks as well. You should see warnings (when running in dev mode) in the console if this is the problem
the reactivity still works, is the thing
can you elaborate on this? how would i pass the component lazily to render?
It's the difference of doing
render(<App />)
vs render(() => <App />)
IIRCWhat if I'm doing
render(() => App(props))
Cause that's what I'm doingNot sure about the effect of that on owners / the above problem, but you definitely should never call a component function directly
Either do
createComponent(App, props)
, or untrack(() => App(props))
(which is what the createComponent function does, though in dev mode it does some other stuff too)
In general, calling a component function directly means that any update to a prop will cause the whole component to rerender (a la react) which is pretty bad in a solid app