Using 'createMemo' inside JSX (to render things which are only available in sections of UI)
I am trying to figure out how to
createMemo
for information, which is only relevant to some sections of the UI (which are rendered conditionally). Top-level (typical) createMemo
will crash because the data based on which I'd like to compute it is not available in the entire component (but it is guaranteed to be available for some sections when those sections pass conditional rendering).
Self-contained example
Gist: in case array()
is not null
, we'd like to display UI about it, which includes its sum in two different places. Challenge is to do it without double-computation and code-duplication.3 Replies
Code:
Here, two sections of UI compute the same summation code. This way it works as expected and never crashes, but there is code duplication and re-computation.
Logical step is to
createMemo
with the said computation. But, in case the lines with createMemo
are uncommented (even if arraySum()
invocations are not), the code above crashes sometimes when array()
becomes null
. Specifically, when len()
crosses 0 to -1 or 5 to -3: sometimes it crashes and sometimes it works as expected.
What is the most robust and idiomatic way to achieve it?Maybe add to the range function :
Array(Math.max(b - a,0))
so that is never negative.
I‘d also put the sum inside a createMemo outside the JSX and just have a early return if !len()
Also have a look at the Show
and Switch/Match
components (especially the callback variants because the also memo the checked condition.)Thanks for a reply. Yes, I thought of those. Those would not crash. Alternatively, one may insert
if (!array()) return 0
inside createMemo
.
But those all are kinda band-aid solutions with code and execution duplication (first we'll check for array()
inside JSX, then we'll check for array()
again inside createMemo
. In case we have more "dependencies" more duplicated "safe guards" will be needed - not nice.
In other words: I'm not looking for any way to get this specific example to not crash. The example is just for clarity.
I'm looking for an elegant way for how to solve it in an elegant way (without duplication) in general.
I looked into Show
with a callback. It indeed works for this specific example:
is robust and I might use it in some situations. Surprisingly, even just using array()
(which didn't work with ternary) works without crashes inside <Show>
. This seems like magic. Isn't ternary ? :
operator supposed to be compiled to the same thing by SolidJS compiler? At the same time, I couldn't make my own custom component <Scope>
to provide a similar kind of magic guard.
The main reason why this might often not work in general case is because oftentimes the desired check is not simply null
vs not-null, but a check for a type of discriminated union: