[]previous and next page

Control flow

Show and Switch decide what is on the page. Only the branch that changes is built or removed.

For agentsUpdated
Show the code
Steps.tsxtsx
import { useStore } from "@shadow-js/core";
import { Match, Show, Switch } from "@shadow-js/web";

type Step = "idle" | "loading" | "done";

export function Steps() {
  const [step, setStep] = useStore<Step>("idle");

  return (
    <div class="stack">
      <div class="row">
        {(["idle", "loading", "done"] as const).map((name) => (
          <button type="button" aria-pressed={step() === name} onClick={() => setStep(name)}>
            {name === "idle" ? "Idle" : name === "loading" ? "Loading" : "Done"}
          </button>
        ))}
      </div>
      <Switch fallback={<p>Nothing has happened yet.</p>}>
        <Match when={step() === "loading"}>
          <p>Fetching.</p>
        </Match>
        <Match when={step() === "done"}>
          <p>Finished.</p>
        </Match>
      </Switch>
      <Show when={step() !== "idle"}>
        <p>Not idle any more.</p>
      </Show>
    </div>
  );
}

Show renders its children while when is truthy and its fallback otherwise. Switch renders the first Match whose when is truthy, or its fallback. A branch is created when it is first shown, not before, and when it goes away its effects stop, its onCleanup callbacks run and its DOM is removed. While a branch stays shown, its own bindings update it in place.

Truthy means JavaScript truthy#

0, "", NaN, null, undefined and false are falsy. Everything else is truthy, [] and {} included. So <Show when={items.length}> hides the list when it is empty, and <Show when={user}> shows it for any object.

A branch that needs the value#

A function as the child receives an accessor of the truthy value, so you do not need a non-null assertion:

Show the code
Greeting.tsxtsx
import { useStore } from "@shadow-js/core";
import { Show } from "@shadow-js/web";

export function Greeting() {
  const [session] = useStore<{ user: { name: string } | null }>({ user: { name: "Ada" } });

  return <Show when={session.user}>{(current) => <p>Hello {current().name}</p>}</Show>;
}

A ternary or && in JSX is compiled the same way: it rebuilds only when the condition flips.

Go deeper#

Control flow also covers Dynamic, Portal, lazy components, keyed children and exactly what each component rebuilds.