S
SolidJS•4mo ago
pao ramen

onCleanup and props

I thought I knew how onCleanup works.. but I don't. It would be great to understand the component lifecycle since the documentation barely explains how createEffect/onMount/onCleanup really work. Here is the piece of code that I find strange:
function Component(props: { post: Post}) {
onCleanup(() => console.log(props.post.id)) // this breaks, since post is null on cleanup?
return <span>{post.title}</span>
}

function Component(props: { post: Post}) {
const post = createMemo(() => props.post)
onCleanup(() => console.log(post().id)) // but this works
return <span>{post.title}</span>
}
function Component(props: { post: Post}) {
onCleanup(() => console.log(props.post.id)) // this breaks, since post is null on cleanup?
return <span>{post.title}</span>
}

function Component(props: { post: Post}) {
const post = createMemo(() => props.post)
onCleanup(() => console.log(post().id)) // but this works
return <span>{post.title}</span>
}
It would be great to understand why props are null during cleanup, and why memos are not. And perhaps document it, since seems rather obscure.
19 Replies
zulu
zulu•4mo ago
how do you trigger the cleanup?
Madaxen86
Madaxen86•4mo ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
zulu
zulu•4mo ago
it does not work for me, if I use it the way I think the OP is using it also found another bug so thanks
Madaxen86
Madaxen86•4mo ago
I don't know what you mean. Props are not null during onCleanup https://playground.solidjs.com/anonymous/e3e66459-30c6-4ef3-b014-77b37503516f
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
zulu
zulu•4mo ago
GitHub
throwing in onCleanup callback breaks reactivity · Issue #2496 · ...
Describe the bug throwing in onCleanup breaks reactivity For example a &lt;Comp&gt; is conditionally rendered and it has a cleanup hook when the condition become falsy, the cleanup will be called a...
zulu
zulu•4mo ago
there is a chance the post object that is accessed in the onCleanup is removed and is a part of a conditional rendering. when the cleanup callback is called, the post object might not be set. this is a user code issue not an issue with solid per say. @pao ramen used a memo but he could also use a scoped variable
// if post unset also remove the component
// we might want to keep the post id
// assuming post object it self is not going to change for this component
// without causing a cleanup.

function Component(props: { post: Post}) {
const post_id = props.post.id
onCleanup(() => console.log(post_id )) // but this works
return <span>{post.title}</span>
}
// if post unset also remove the component
// we might want to keep the post id
// assuming post object it self is not going to change for this component
// without causing a cleanup.

function Component(props: { post: Post}) {
const post_id = props.post.id
onCleanup(() => console.log(post_id )) // but this works
return <span>{post.title}</span>
}
although the memo might be safer ( in some cases )
Madaxen86
Madaxen86•4mo ago
Well now I've found that when using Shows callback like
<Show when={show() && post()}>
{(p) => <Comp post={p()} />}
</Show>
<Show when={show() && post()}>
{(p) => <Comp post={p()} />}
</Show>
now p will be undefined When using it with keyed it works again 🤨
<Show when={show() && post()} keyed>
{(p) => <Comp post={p} />}
</Show>
<Show when={show() && post()} keyed>
{(p) => <Comp post={p} />}
</Show>
Probably has to do with Show using createMemo which evaluates eager. Then this would be obsolete with 2.0. And actually nothing that can be done now.
zulu
zulu•4mo ago
that is another related case. ( post() being part of the conditional rendering
zulu
zulu•4mo ago
actually this case is guarded and I am getting https://playground.solidjs.com/anonymous/0f910742-775b-4db8-a1be-69bd800f7bc8 Uncaught Error: Stale read from <Show>.
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Madaxen86
Madaxen86•4mo ago
in the playground its Uncaught Error: Script error. https://playground.solidjs.com/anonymous/ff587a0c-fac3-497b-acff-b2a086a94def
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
zulu
zulu•4mo ago
No description
Madaxen86
Madaxen86•4mo ago
It gets weirder. In Safari it's the script error in Chrome I also get Stale read !?!?
zulu
zulu•4mo ago
safari try checking the browser console not the playground one what do you get?
Madaxen86
Madaxen86•4mo ago
in Safari parentId or nodeId could not be resolved to a node
pao ramen
pao ramenOP•4mo ago
it may be a user code issue, but I still don't understand why. The documentation is not very thorough about the lifecycle of components. I would really like to understand why is that the case so I can re-evaluate my mental model and not fall for this trap again.
zulu
zulu•4mo ago
see this message first https://discord.com/channels/722131463138705510/1376532857849249803/1376600624690495602 need to see your case, to understand the source of your issue, then we can work on the better mental model.
pao ramen
pao ramenOP•4mo ago
I'm using solid router, and I basically switch from one route to another.
zulu
zulu•4mo ago
anything in the route change, that may unset the post you are passing ?
zulu
zulu•4mo ago
you can try put a working example here https://stackblitz.com/ if it is too much for you you can look into the example with the <Show> and see that when you pass a "state" as a prop, and the component that depends on it as a prop and also conditionally renders based on that state. When that state become Falsy, and the component is removed the cleanup hook is called, with the prop state already being unassigned.
StackBlitz | Instant Dev Environments | Click. Code. Done.
StackBlitz is the collaborative browser-based IDE for web developers. StackBlitz eliminates time-consuming local configuration and lets developers spend more time building.

Did you find this page helpful?