Switch(複数条件)
複数の相互排他的な条件を処理します。
基本的な使い方
import { createSignal, Switch, Match } from '@luna_ui/luna';
function StatusBadge() {
const [status, setStatus] = createSignal("pending");
return (
<Switch fallback={<span>不明</span>}>
<Match when={status() === "pending"}>
<span class="yellow">保留中</span>
</Match>
<Match when={status() === "active"}>
<span class="green">アクティブ</span>
</Match>
<Match when={status() === "error"}>
<span class="red">エラー</span>
</Match>
</Switch>
);
}
Switch vs ネストした Show
ネストした Show(冗長)
<Show when={status() === "loading"} fallback={
<Show when={status() === "error"} fallback={
<Show when={status() === "success"} fallback={
<DefaultView />
}>
<SuccessView />
</Show>
}>
<ErrorView />
</Show>
}>
<LoadingView />
</Show>
Switch(きれい)
<Switch fallback={<DefaultView />}>
<Match when={status() === "loading"}>
<LoadingView />
</Match>
<Match when={status() === "error"}>
<ErrorView />
</Match>
<Match when={status() === "success"}>
<SuccessView />
</Match>
</Switch>
値の抽出
<Show> と同様に、<Match> は truthy 値を抽出できます:
const [response, setResponse] = createSignal(null);
<Switch>
<Match when={response()?.error}>
{(error) => <p>Error: {error.message}</p>}
</Match>
<Match when={response()?.data}>
{(data) => <DataView data={data} />}
</Match>
</Switch>
順序が重要
最初にマッチした <Match> が勝ちます:
const [score, setScore] = createSignal(85);
<Switch fallback={<p>F</p>}>
<Match when={score() >= 90}><p>A</p></Match>
<Match when={score() >= 80}><p>B</p></Match> {/* 85 でこれがマッチ */}
<Match when={score() >= 70}><p>C</p></Match>
<Match when={score() >= 60}><p>D</p></Match>
</Switch>
一般的なパターン
タブコンテンツ
const [tab, setTab] = createSignal("overview");
<div>
<nav>
<button onClick={() => setTab("overview")}>概要</button>
<button onClick={() => setTab("details")}>詳細</button>
<button onClick={() => setTab("reviews")}>レビュー</button>
</nav>
<Switch>
<Match when={tab() === "overview"}>
<OverviewPanel />
</Match>
<Match when={tab() === "details"}>
<DetailsPanel />
</Match>
<Match when={tab() === "reviews"}>
<ReviewsPanel />
</Match>
</Switch>
</div>
ステップウィザード
const [step, setStep] = createSignal(1);
<div>
<Switch>
<Match when={step() === 1}>
<Step1 onNext={() => setStep(2)} />
</Match>
<Match when={step() === 2}>
<Step2
onBack={() => setStep(1)}
onNext={() => setStep(3)}
/>
</Match>
<Match when={step() === 3}>
<Step3
onBack={() => setStep(2)}
onSubmit={handleSubmit}
/>
</Match>
</Switch>
<p>ステップ {step()} / 3</p>
</div>
試してみよう
3つの状態(赤、黄、緑)を持つ信号機コンポーネントを作成し、それらを循環:
解答
function TrafficLight() {
const [light, setLight] = createSignal("red");
const cycle = () => {
setLight(current => {
switch (current) {
case "red": return "green";
case "green": return "yellow";
case "yellow": return "red";
}
});
};
return (
<div>
<div class="traffic-light">
<Switch>
<Match when={light() === "red"}>
<div class="light red">止まれ</div>
</Match>
<Match when={light() === "yellow"}>
<div class="light yellow">注意</div>
</Match>
<Match when={light() === "green"}>
<div class="light green">進め</div>
</Match>
</Switch>
</div>
<button onClick={cycle}>次へ</button>
</div>
);
}
次へ
onMount → について学ぶ