S
SolidJS14mo ago
Mr Void

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:
computations created outside a `createRoot` or `render` will never be disposed
computations created outside a `createRoot` or `render` will never be disposed
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.tsx
Nedkan
StackBlitz
Solidjs - Templates (forked) - StackBlitz
Vite + solid templates
3 Replies
foolswisdom
foolswisdom14mo ago
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 solid
Mr Void
Mr VoidOP14mo ago
Thank you for explaining this to me in detail, I appreciate namastedoge 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
foolswisdom
foolswisdom14mo ago
👍 Oh yeah, a portal wrapped in show is usually what I do 😅
Want results from more Discord servers?
Add your server