Conditional Rendering with Show
Why Solid uses a <Show> component instead of JavaScript ternaries or && for conditional UI.
読了時間 2 分
In React, conditional rendering is usually plain JavaScript: a ternary, &&, or an early return. In Solid, those patterns work, but <Show> is the idiomatic tool, and understanding why reveals something important about how Solid's compiler optimizes JSX.
The problem with a plain ternary
function Profile(props) {
return (
<div>
{props.user ? <UserCard user={props.user} /> : <p>Not logged in</p>}
</div>
);
}This works, but it's less efficient than it looks. Every time props.user changes, Solid's compiled output has to re-evaluate the whole ternary expression and potentially tear down and recreate the DOM subtree on either side, because a raw JavaScript conditional gives the compiler no structure to optimize around — it just sees "an expression that returns different JSX."
Show gives the compiler a stable shape
import { Show } from "solid-js";
function Profile(props) {
return (
<Show when={props.user} fallback={<p>Not logged in</p>}>
<UserCard user={props.user} />
</Show>
);
}<Show> is a component, not special syntax — but it's designed so Solid can keep the "true" and "false" branches as stable, cached pieces of DOM, switching between them (or toggling visibility) without recreating everything from scratch on every change. when takes the condition; fallback is what renders when it's falsy; the children render when it's truthy.
Show gives you the resolved value, not just a boolean
A detail that's easy to miss: the when prop can be more than a boolean, and <Show> passes the resolved (truthy) value into its children as a callback argument:
<Show when={props.user} fallback={<p>Not logged in</p>}>
{(user) => <p>Welcome back, {user().name}!</p>}
</Show>Using children as a function like this avoids re-checking props.user for null inside the branch — <Show> already confirmed it's truthy before calling this function, and TypeScript can narrow the type accordingly if you're using solid-ts.
Nesting and combining conditions
<Show when={isLoggedIn()}>
<Show when={hasSubscription()} fallback={<UpgradePrompt />}>
<PremiumContent />
</Show>
</Show>Nested <Show>s compose naturally for multi-step conditions, each with its own fallback. This tends to read more clearly than stacking ternaries or && chains once you have more than one condition to check.
When a plain ternary is still fine
For trivial, non-DOM-heavy conditions — swapping a class name, a short inline string — a ternary is still perfectly reasonable:
<span class={isActive() ? "active" : "inactive"}>{label}</span>The guidance isn't "never use JavaScript conditionals in JSX" — it's "reach for <Show> when you're conditionally rendering actual elements or components," since that's where the compiler's optimizations for stable branches actually pay off.