Stale read in <List><Show><List>
https://playground.solidjs.com/anonymous/ccb906d4-c9f1-437f-9f72-e94279b0e25d
I am stumped, I don't know why the stale read is happening, I don't know why it's triggered by that stream of states and not others.
Note that the playground doesn't render the error message correctly, here's the dev message:
Uncaught Error: Attempting to access a stale value from <Show> that could possibly be undefined. This may occur because you are reading the accessor returned from the component at a time where it has already been unmounted. We recommend cleaning up any stale timers or async, or reading from the initial condition.
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
4 Replies
Well I'm starting to think this is actually a bug in
<Show>
in that stale signal reads should not be an exception
This appears to be caused by the ordering of memo updates and destruction. createMemo
s listeners are not deferred and run immediately, even if those listeners are owned by another createMemo
that will destroy them just as soon as it gets time to run
or maybe
<Show>
's condition
and conditionValue
get updated, then, since the child of the inner <List>
is listening to the same signal that caused condition
to update, it gets to update, too. When it reads from the stale accessor, it sees the updated value of condition
and an exception gets thrownhttps://playground.solidjs.com/anonymous/dff1aaa6-18fe-44aa-b5f9-2e349f16d2a3
it basically boils down to recomputation of a child node that access the condition as a result of write operation that negates the condition
with that assumption, that gives us https://playground.solidjs.com/anonymous/61aa97b9-7680-4f21-a7d8-8950bc0a48c9
essentially what
List
or indexArray
helper is doing under the hood
i know that it was done to detect cases like this but it isn't that obvious that this might happen in real world scenarios
here, the node that triggers the error eventually gets cleaned up as a result of its reparent recomputingI'm not sure if this is a scheduling bug, in the reactive system itself, or if its an issue with
Show
if it's the latter then something like
suppresses the error in this case
https://playground.solidjs.com/anonymous/2d2e421b-7498-4a9d-9eef-f25e0265ad85
solid might have a better hook than queueMicrotask, to wait for the last tick before checking to make sure it was disposed of
downside is: this secretly still does extra work, unlike the exception which terminates the potentially expensive updateI'm just going to write here to remind myself to look at this