rendering both branches even if they aren't both in the DOM, so I figured it should be possible to make a variant of
Show
Show
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.;}