Warning when modal uses state
I have created a context provider
ModalProvider
that is meant to display a modal whenever it's visible
state is true. This container is displayed on top of any other element that exists within the App
.
It worked well, until I created a state within the modal itself - at which point it began throwing the following warning:
Why does this happen when myModal
component is using a state? ( this is displayed in the ModalProvider
)
https://stackblitz.com/edit/solidjs-templates-bnxz3s?file=src%2FApp.tsx3 Replies
This is because you are using effects (implicitly, most JSX expressions containing a function call or property access get wrapped in effects - or getters if they're component props) outside of an owner. I'll write out a full explanation, but the short of it is that you are creating a component (with effects) in an event handler, which is outside of the component tree.
To clarify what this means: in general, effects and the like need to be cleaned up once no longer needed (or else you'll have a memory leak), and the mechanism solid uses for doing that is to have an "owner" which owns the effect, and when a cleanup is called for the owner, the owner disposes of all effects (and child nested owners).
Now, normally, these owners are created for you. When you call render on the root of the app, it creates a root, and Show components (or ternary expressions in JSX, which compile to Show thanks to the compiler) also create a root (so when the
when
prop becomes false, the child component gets cleaned up), and so on. So, wherever you are in the component tree, you always have an owner determining when to cleanup effects.
However, event listener callbacks do not have owners (only components and effects/memos etc. do, if they are created inside an owner context). So when you create a component inside a callback, the component and its listeners can never get cleaned up, hence the warning message.
The easy way of doing something like this is for the modal to be a child of a show component, which would only show based on a signal containing the right props for the modal. Another way would be to manually manage the owners yourself. Checkout createRoot
.
On another note, you shouldn't call components directly. Either use JSX, or use createComponent(myModal, props)
(which is what JSX compiles to), or untrack(() => myModal(...))
, which is what createComponent
itself does, in addition to some stuff for dev tools. Calling components directly can cause a complete component rerender when props change, which is not what we want in solidThank you for explaining this to me in detail, I appreciate
I think I now understand what's going on. After some more reading online, I came across <Portal> which seems to be doing about the same thing in an easier way 😅 and with this, the warning seems to be gone
👍
Oh yeah, a portal wrapped in show is usually what I do 😅