Code review/can anyone understand this primitive I wrote
Primitive and tests at: https://playground.solidjs.com/anonymous/559a4311-46a1-4ec3-b9e0-00c2b8f258a6
The SolidJS docs make a big deal about
so I figured it should be possible to make a variant of
The SolidJS docs make a big deal about
SuspenseSuspense rendering both branches even if they aren't both in the DOM,so I figured it should be possible to make a variant of
ShowShow that only renders it's main children once.export function RenderOnceShow<T>(props: {
when: NonNullable<T> | undefined;
fallback?: JSX.Element;
children: (t: Accessor<NonNullable<T>>) => JSX.Element;
}) {
// Avoid unneccessary re-renders of the fallback
const fallback = children(() => props.fallback);
// TRACKS: the first time props.when changes from undefined to defined
return createMemo(() => {
const when = untrack(() => props.when);
if (when !== undefined) {
// nothing is tracked here.
// so once this branch has run the memo will never run again.
const [t, setT] = createSignal<NonNullable<T>>(when);
// memo here so props.children is only called once
// TRACKS: props.children
const content: Accessor<JSX.Element> = createMemo(() => {
// track the access to children
const children = props.children;
return createComponent(children, t);
});
// each time props.when changes,
// setT, so long as props.when is not undefined
createComputed(() => {
const when = props.when;
if (when === undefined) return;
setT(() => when);
});
// TRACKS: props.when, fallback, content
return createMemo(() =>
props.when === undefined ? fallback() : content(),
);
} else {
// this is the only tracked signal in this memo
// putting props.when behind a createMemo ensures that the outer memo
// only re-evaluates if props.when is no longer undefined
createMemo(() => props.when)();
return fallback();
}
}) as unknown as JSX.Element; // Apparently this is ok? `Show` does it.;
}export function RenderOnceShow<T>(props: {
when: NonNullable<T> | undefined;
fallback?: JSX.Element;
children: (t: Accessor<NonNullable<T>>) => JSX.Element;
}) {
// Avoid unneccessary re-renders of the fallback
const fallback = children(() => props.fallback);
// TRACKS: the first time props.when changes from undefined to defined
return createMemo(() => {
const when = untrack(() => props.when);
if (when !== undefined) {
// nothing is tracked here.
// so once this branch has run the memo will never run again.
const [t, setT] = createSignal<NonNullable<T>>(when);
// memo here so props.children is only called once
// TRACKS: props.children
const content: Accessor<JSX.Element> = createMemo(() => {
// track the access to children
const children = props.children;
return createComponent(children, t);
});
// each time props.when changes,
// setT, so long as props.when is not undefined
createComputed(() => {
const when = props.when;
if (when === undefined) return;
setT(() => when);
});
// TRACKS: props.when, fallback, content
return createMemo(() =>
props.when === undefined ? fallback() : content(),
);
} else {
// this is the only tracked signal in this memo
// putting props.when behind a createMemo ensures that the outer memo
// only re-evaluates if props.when is no longer undefined
createMemo(() => props.when)();
return fallback();
}
}) as unknown as JSX.Element; // Apparently this is ok? `Show` does it.;
}Quickly discover what the solid compiler will generate from your JSX template

Solid API